Problem Background
I'm creating a tool, tha generates MVC solutions(*.sln) and building(with msbuild) them so they could be deployed. Tool requires .NET Framework 4.5.2.
Now I want to generate ASP.NET Core MVC application. Such applications could be run under 4.5.X, but I'm unsure if msbuild could handle project.json(so i'm using packages.config) and I cannot install .NET Core as every tutorial indicate as prerequisite for developing ASP.NET Core. Currently I'm planning to deploy generated applications on Windows.
The Problem:
So instead of .NET Core project I've created a simple console application: There I've installed there all packages needed, like:
<package id="Microsoft.AspNetCore.Mvc" version="1.0.1" targetFramework="net452" />
And SelfHosted the application using Kestrel:
public class Program {
static void Main() {
var host = new WebHostBuilder()
.UseKestrel()
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
}
I've added Controller with a View. When I do a request, controller is hit, but View cannot be compiled in runtime:
Is this behavior related to the fact I'm using Console Application and not ASP.NET Core Web Application? Is it possible to create a full-featured MVC application as a simple console application?
UPDATE:
I think I've found a workaround inspired from reading github issues:
public void ConfigureServices(IServiceCollection services) {
services.AddMvc()
.AddRazorOptions(options => {
var previous = options.CompilationCallback;
options.CompilationCallback = context => {
previous?.Invoke(context);
var refs = AppDomain.CurrentDomain.GetAssemblies()
.Where(x => !x.IsDynamic)
.Select(x => MetadataReference.CreateFromFile(x.Location))
.ToList();
context.Compilation = context.Compilation.AddReferences(refs);
};
});
}
That seems to make Razor to render my view. But I'm not sure yet if it can be accepted as a solution.
Right now, it's not possible to build a .NET Core app using MSBuild, but it's possible to create a console application (not .NET Core) and add the same packages using NuGet (step-by-step below).
According to this road map, it will be possible in the near future.
Info from the link above:
Q4 2016 / Q1 2017
This will be the first minor update, mainly focused on replacing .xproj/project.json with .csproj/MSBuild. Project format update should be automatic. Just opening a 1.0 project will update it to the new project format. There will also be new functionality and improvements in the runtime and libraries.*
EDIT (steps to create a console app with Kestrel):
I created a Console application (not .NET Core console) and I was able to run Kestrel with a simple MVC API.
Here's what I did:
I saw the dependencies I use in an existing .NET Core app, then, I added them as a NuGet reference:
"Microsoft.AspNetCore.Mvc": "1.0.0",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
"Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
"Microsoft.Extensions.Configuration.Json": "1.0.0",
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0"
Modified the main method:
static void Main(string[] args) {
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
Created a Startup.cs (UPDATED with the workaround provided in the question):
public class Startup {
public Startup(IHostingEnvironment env) {
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
private IHostingEnvironment CurrentEnvironment { get; set; }
private IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services) {
services.AddMvc().AddRazorOptions(options => {
var previous = options.CompilationCallback;
options.CompilationCallback = context => {
previous?.Invoke(context);
var refs = AppDomain.CurrentDomain.GetAssemblies()
.Where(x => !x.IsDynamic)
.Select(x => MetadataReference.CreateFromFile(x.Location))
.ToList();
context.Compilation = context.Compilation.AddReferences(refs);
};
});
}
public void Configure(IApplicationBuilder app) {
app.UseStaticFiles();
app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
Add a class to be my MVC Controller:
[Route("api/[controller]")]
public class ValuesController : Controller {
// GET api/values
[HttpGet]
public IEnumerable<string> Get() {
return new string[] { "value1", "value2" };
}
I had to copy manually the libuv.dll
file to the bin folder because I was getting an error.
With these steps, I was able to run my console application. In the image below, you can see my project structure and Kestrel running:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With