7

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: enter image description here 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: enter image description here

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.

11
  • ASP.NET Core application is already a console application (hosted by kestrel or WebListener). What's your question? Also, when you target .NET 4.5.2 you don't need .NET Core runtime. You need it only if you target netcopreapp1.0 obviously Commented Oct 19, 2016 at 10:19
  • @Tseng If I understand correctly, I have to create ASP.NET Core application as .NET Core project. Instead, I'm creating it as simple Console Application. So the question is, if creating it as not .NET Core specific project could work? Commented Oct 19, 2016 at 10:24
  • Is there a reason for you not installing the .Net Core SDK? Besides that, Microsoft recommend IIS for hosting your app, so, you would need .NET Core Windows Server Hosting to use your IIS as a reverse proxy to kestrel. Commented Oct 19, 2016 at 10:42
  • @FabricioKoch Yes, there is such reason: I cannot install .Net Core SDK, because it would require the users of my tool to also have it installed(since I'm acutally compiling web application on client side). The generated application would be self-hosted only on client machine, so user could see what web-site is generated. IIS will be used for the final deployment of application without Kestrel. Commented Oct 19, 2016 at 10:46
  • @3615: No, you don't have to create it as .NET Core project. in VS Go to File -> New -> Project -> Search "ASP.NET Core" -> ASP.NET Core Web Application (.NET Framework). This creates a ASP.NET Core project which targets .NET Framework 4.5.2 (but you can change it by editing project.json) Commented Oct 19, 2016 at 11:27

1 Answer 1

8

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:

enter image description here

Sign up to request clarification or add additional context in comments.

9 Comments

That's not exactly what I'm asking about, but thanks for your input, you've got my upvote. I was suspecting that I would not be able to build .NET Core app using MSBuild, that's why I went for a simple console application. That one is building fine, because there is no project.json, just *.csproj and packages.config. But for some reason Razor is unable to compile Views. Is this somehow related to the fact I'm using Console Application Project? If so, how exactly?
@3615 I was able to run it as a console application. Check my updated answer. Maybe it can help you to solve your problem.
Great! We are getting closer to my question :) I also was able to make controller working (as you could see in my question, I've mentioned that my controller is hit). And I've also created a post build event for libuv using xcopy. But could you add some Razor views and call it from controller using View() method and see if it gives no runtime exceptions?
@3615: Did you copy over your view folder to the build/output directory?
@FabricioKoch Yes, that's another problem I was going to think about later. Just set Copy to Ouput Directory to "Copy if newer" and it's coppied on build.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.