vNext:使用剃刀视图而不托管的控制台应用程序 [英] vNext: Console app that uses razor views without hosting

查看:271
本文介绍了vNext:使用剃刀视图而不托管的控制台应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建执行一些文件转换的控制台应用程序。这些转换很容易完成,从输入文件创建一个模型,然后为输出执行剃刀模型。



要在IDE中工作,我使用Visual Studio 2015预览和创建了一个使用MVC的vnext控制台应用程序。 (你得到剃刀支持开箱即可)。为了让这一切工作,你需要托管MVC应用程序,而最便宜的方式做到这一点是托管是通过一个WebListener。所以我主持MVC应用程序,然后通过http:// localhost:5003 / etc / etc调用它来获得构造输出的渲染视图。



但是控制台应用程序不应该监听/使用端口。它只是一个用于文件转换的命令行工具。如果多个实例同时运行,它们将争取在同一端口上托管页面。 (这可以通过动态选择一个端口来防止粗糙,但这不是我正在寻找)



所以我的问题是,你会如何得到这个工作没有使用一个端口,但使用尽可能多的vnext框架。



简而言之:如何使用cshtml文件,我传递模型在控制台应用程序,不使用



以下是我目前使用的一些代码:



Program.cs

 使用Microsoft.AspNet.Hosting; 
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using System;
using System.IO;
using System.Net.Http;
使用System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;

命名空间ConsoleTest
{
public class Program
{
private readonly IServiceProvider _hostServiceProvider;

public程序(IServiceProvider hostServiceProvider)
{
_hostServiceProvider = hostServiceProvider;
}

public async任务< string> GetWebpageAsync()
{
using(var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(http:// localhost:5003 / home / svg ?idx = 1);
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(text / xml));
return await httpClient.GetStringAsync();
}
}

public任务< int> Main(string [] args)
{
var config = new Configuration();
config.AddCommandLine(args);

var serviceCollection = new ServiceCollection();
serviceCollection.Add(HostingServices.GetDefaultServices(config));
serviceCollection.AddInstance< IHostingEnvironment>(new HostingEnvironment(){WebRoot =wwwroot});
var services = serviceCollection.BuildServiceProvider(_hostServiceProvider);

var context = new HostingContext()
{
Services = services,
Configuration = config,
ServerName =Microsoft.AspNet.Server.WebListener ,
ApplicationName =ConsoleTest
};

var engine = services.GetService< IHostingEngine>();
if(engine == null)
{
throw new Exception(TODO:IHostingEngine service not available exception);
}

使用(engine.Start(context))
{
var tst = GetWebpageAsync();
tst.Wait();
File.WriteAllText(@C:\\result.svg,tst.Result.TrimStart());

Console.WriteLine(Started the server ..);
Console.WriteLine(按任意键停止服务器);
Console.ReadLine();
}
return Task.FromResult(0);
}
}
}

Startup.cs

 使用Microsoft.AspNet.Builder; 
using Microsoft.Framework.DependencyInjection;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.ConfigurationModel;

命名空间ConsoleTest
{
public class Startup
{
public IConfiguration Configuration {get;私人集}

public void ConfigureServices(IServiceCollection services)
{
//将MVC服务添加到服务容器
services.AddMvc();
}

public void Configure(IApplicationBuilder app)
{
//配置WebFx
app.UseMvc(routes =>
{
routes.MapRoute(
null,
{controller} / {action},
new {controller =Home,action =Index});
});
}
}
}


解决方案>

我使用以下代码解决了它:



Program.cs

  using System; 
using System.Threading.Tasks;
using Microsoft.AspNet.TestHost;
using Microsoft.AspNet.Builder;
使用Microsoft.Framework.Runtime.Infrastructure;

命名空间ConsoleTest
{
public class Program
{
private Action< IApplicationBuilder> _app;
private IServiceProvider _services;

public async任务< string> TestMe()
{
var server = TestServer.Create(_services,_app);
var client = server.CreateClient();
return await client.GetStringAsync(http:// localhost / home / svg?idx = 1);
}

public void Main(string [] args)
{
_services = CallContextServiceLocator.Locator.ServiceProvider;
_app = new Startup()。配置;

var x = TestMe();
x.Wait();
Console.WriteLine(x.Result);

Console.ReadLine();
}
}
}

Startup.cs

 使用Microsoft.AspNet.Builder; 
using Microsoft.Framework.DependencyInjection;
using Microsoft.AspNet.Routing;

命名空间ConsoleTest
{
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseServices (services =>
{
//将MVC服务添加到服务容器
services.AddMvc();
});
//配置WebFx
app.UseMvc(routes =>
{
routes.MapRoute(
null,
{controller} / {action },
new {controller =Home,action =Index});
});
}
}
}


I am creating console application that does some file conversions. These conversions are easily done creating a model from the input file and then executing razor models for the output.

To have this working in the IDE I used Visual Studio 2015 preview and created a vnext console application that uses MVC. (You get razor support out of the box then). To get this all working you need to host the MVC app though, and the cheapest way to do that is hosting is through a WebListener. So I host the MVC app and then call it through "http://localhost:5003/etc/etc" to get the rendered views that construct the output.

But the console app is not supposed to listen to/use a port. It is just a command line tool for file conversions. If multiple instances would run at the same time they would fight to host the pages on the same port. (This could of coarse be prevented by choosing a port dynamically, but this is not what I am looking for)

So my question is how would you get this working without using a port, but using as much of the vnext frameworks as possible.

In short: how can I use cshtml files that I pass models in a console app that does not use a port using the vnext razor engine.

Here is some code I currently use:

Program.cs

using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace ConsoleTest
{
    public class Program
    {
        private readonly IServiceProvider _hostServiceProvider;

        public Program(IServiceProvider hostServiceProvider)
        {
            _hostServiceProvider = hostServiceProvider;
        }

        public async Task<string> GetWebpageAsync()
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.BaseAddress = new Uri("http://localhost:5003/home/svg?idx=1");
                httpClient.DefaultRequestHeaders.Accept.Clear();
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
                return await httpClient.GetStringAsync("");
            }
        }

        public Task<int> Main(string[] args)
        {
            var config = new Configuration();
            config.AddCommandLine(args);

            var serviceCollection = new ServiceCollection();
            serviceCollection.Add(HostingServices.GetDefaultServices(config));
            serviceCollection.AddInstance<IHostingEnvironment>(new HostingEnvironment() { WebRoot = "wwwroot" });
            var services = serviceCollection.BuildServiceProvider(_hostServiceProvider);

            var context = new HostingContext()
            {
                Services = services,
                Configuration = config,
                ServerName = "Microsoft.AspNet.Server.WebListener",
                ApplicationName = "ConsoleTest"
            };

            var engine = services.GetService<IHostingEngine>();
            if (engine == null)
            {
                throw new Exception("TODO: IHostingEngine service not available exception");
            }

            using (engine.Start(context))
            {
                var tst = GetWebpageAsync();
                tst.Wait();
                File.WriteAllText(@"C:\\result.svg", tst.Result.TrimStart());

                Console.WriteLine("Started the server..");
                Console.WriteLine("Press any key to stop the server");
                Console.ReadLine();
            }
            return Task.FromResult(0);
        }
    }
}

Startup.cs

using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.ConfigurationModel;

namespace ConsoleTest
{
    public class Startup
    {
        public IConfiguration Configuration { get; private set; }

        public void ConfigureServices(IServiceCollection services)
        {
            // Add MVC services to the services container
            services.AddMvc();
        }

        public void Configure(IApplicationBuilder app)
        {
            //Configure WebFx
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    null,
                    "{controller}/{action}",
                    new { controller = "Home", action = "Index" });
            });
        }
    }
}

解决方案

I solved it using the following code:

Program.cs

using System;
using System.Threading.Tasks;
using Microsoft.AspNet.TestHost;
using Microsoft.AspNet.Builder;
using Microsoft.Framework.Runtime.Infrastructure;

namespace ConsoleTest
{
    public class Program
    {
        private Action<IApplicationBuilder> _app;
        private IServiceProvider _services;

        public async Task<string> TestMe()
        {
            var server = TestServer.Create(_services, _app);
            var client = server.CreateClient();
            return await client.GetStringAsync("http://localhost/home/svg?idx=1");
        }

        public void Main(string[] args)
        {
            _services = CallContextServiceLocator.Locator.ServiceProvider;
            _app = new Startup().Configure;

            var x = TestMe();
            x.Wait();
            Console.WriteLine(x.Result);

            Console.ReadLine();
        }
    }
}

Startup.cs

using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;
using Microsoft.AspNet.Routing;

namespace ConsoleTest
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app)
        {
            app.UseServices(services =>
            {
                // Add MVC services to the services container
                services.AddMvc();
            });
            //Configure WebFx
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    null,
                    "{controller}/{action}",
                    new { controller = "Home", action = "Index" });
            });
        }
    }
}

这篇关于vNext:使用剃刀视图而不托管的控制台应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆