In Focus

Converting ASP.NET 5 Beta 8 App To ASP.NET Core RC2

In this article you will learn how to convert ASP.NET 5 Beta 8 Appto ASP.NET Core RC2.

A few months ago I wrote an article about "Upgrading Existing ASP.NET 5 previous versions to Beta 8". Since then I have stuck to using Beta 8 version for building ASP.NET Core app prototypes. Besides being lazy, it was my intent not to upgrade my existing projects to RC1 because I know that RC2 will be released in the near future.

A few days ago Microsoft announced the release of ASP.NET Core RC2. This release succeeds the ASP.NET 5 RC1 release and features a number of updates to enhance compatibility with other .NET frameworks and an improved runtime.

A key change that occurred between Betas and RC2 is the introduction of the .NET command-line interface (CLI). This tool replaces the dnvm, dnx, and dnu utilities with a single tool that handles the responsibilities of these tools. To learn more about the .NET CLI, check out Announcing .NET Core RC2 and .NET Core SDK Preview 1.

If you are working with ASP.NET 5 Beta 8 versions up to this moment and wanted to migrate your app to the latest release which is RC2 as of this writing then this article is for you. Though this article doesn’t list all the changes, this would somehow list the changes for the most basic part so your app can run under RC2 version.

Warning: Spoiler Ahead!

There will be big changes under the hood with the release of ASP.NET Core RC2 so expect a longer list for this conversion.

Let's get Cracking!

First thing you need to do is upgrade your Visual Studio 2015 with Update 2. You can check the release and download the update for Visual Studio here.

Once the setup and configuration is applied in Visual Studio then download the ASP.NET Core RC2 here.

After the installation, make sure to restart your machine to ensure updates will take effect.

In this conversion I’m going to use the ASP.NET MVC 6 project that I’ve demonstrated before. Now let’s start modifying.

global.json Changes

Change your global.json to this:

  1. {  
  2.     "projects": ["src""test"],  
  3.     "sdk":  
  4.     {  
  5.         "version""1.0.0-preview1-002702"  
  6.     }  
  7. }  
Two things we’ve changed there, first was to replace “sources” node to “projects” and then replaced the version from “1.0.0-beta8” to “1.0.0-preview1-002702” – the latest RC2 version as of this writing.

project.json Changes

Dependencies

Add the runtime as a dependency:
  1. "dependencies":  
  2. {  
  3.     "Microsoft.NETCore.App":  
  4.     {  
  5.         "version""1.0.0-rc2-3002702",  
  6.         "type""platform"  
  7.     },  
  8. }  
  • Replace all “Microsoft.AspNet.*” dependencies to “Microsoft.AspNetCore.*”

  • Then replace version suffix from “-beta8” to “-rc2-final”.

    Note: if you are referencing “Microsoft.AspNet.Mvc": "6.0.0-beta8" then make sure to change the version to “1.0.0” so it will look like this "Microsoft.AspNetCore.Mvc": "1.0.0-rc2-final".

  • Next, change the name of all “Microsoft.Framework.*” references to “Microsoft.Extensions.*”.

  • If you are using SQL Server, you will need to change the reference of “EntityFramework.SqlServer” to “Microsoft.EntityFrameworkCore.SqlServer”.

  • After that, change existing assemblies with new names for example:

    "Microsoft.AspNet.IISPlatformHandler">"Microsoft.AspNetCore.Server.IISIntegration"
    "Microsoft.AspNet.Identity.EntityFramework" > "Microsoft.AspNetCore.Identity.EntityFrameworkCore"

  • Add the following configuration and diagnostics references:

    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc2-final",
    "Microsoft.Extensions.Configuration.UserSecrets": "1.0.0-rc2-final",
    "Microsoft.AspNetCore.Diagnostics": "1.0.0-rc2-final",

Frameworks

Change your frameworks section with the following new naming structure:

  1. "frameworks":  
  2. {  
  3.     "netcoreapp1.0":  
  4.     {  
  5.         "imports": [  
  6.             "dotnet5.6",  
  7.             "dnxcore50",  
  8.             "portable-net45+win8"  
  9.         ]  
  10.     }  
  11. },  
Tools

You will need to rename the existing “command” section to “tools” and add the following tools from the preview like this:
  1. "tools":  
  2. {  
  3.     "Microsoft.AspNetCore.Razor.Tools":  
  4.     {  
  5.         "version""1.0.0-preview1-final",  
  6.         "imports""portable-net45+win8+dnxcore50"  
  7.     },  
  8.     "Microsoft.AspNetCore.Server.IISIntegration.Tools":  
  9.     {  
  10.         "version""1.0.0-preview1-final",  
  11.         "imports""portable-net45+win8+dnxcore50"  
  12.     },  
  13.     "Microsoft.EntityFrameworkCore.Tools":  
  14.     {  
  15.         "version""1.0.0-preview1-final",  
  16.         "imports": [  
  17.             "portable-net45+win8+dnxcore50",  
  18.             "portable-net45+win8"  
  19.         ]  
  20.     },  
  21.     "Microsoft.Extensions.SecretManager.Tools":  
  22.     {  
  23.         "version""1.0.0-preview1-final",  
  24.         "imports""portable-net45+win8+dnxcore50"  
  25.     },  
  26.     "Microsoft.VisualStudio.Web.CodeGeneration.Tools":  
  27.     {  
  28.         "version""1.0.0-preview1-final",  
  29.         "imports": [  
  30.             "portable-net45+win8+dnxcore50",  
  31.             "portable-net45+win8"  
  32.         ]  
  33.     }  
  34. },  
publishOptions

Next remove the existing “bundleExclude” and “bundle” config section and replace them with the new publishOptions section like:
  1. "publishOptions":  
  2. {  
  3.     "include": [  
  4.         "wwwroot",  
  5.         "Views",  
  6.         "appsettings.json",  
  7.         "web.config"  
  8.     ]  
  9. }  
Add the buildOptions and runtimeOptions sections like so:
  1. "buildOptions":  
  2. {  
  3.     "emitEntryPoint"true,  
  4.     "preserveCompilationContext"true  
  5. },  
  6. "runtimeOptions":  
  7. {  
  8.     "gcServer"true  
  9. },  
Setting the “preserveCompilationContext” to “true” will compile Views. This setting is important especially if you are using a strongly-typed view that needs to be compiled.

Add the new “Scripts” section:
  1. "scripts": {  
  2.    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]  
  3. }  
Wrapping all the Changes

Here’s my updated project.json file after putting altogether the changes:
  1. {  
  2.     "dependencies":  
  3.     {  
  4.         "Microsoft.NETCore.App":  
  5.         {  
  6.             "version""1.0.0-rc2-3002702",  
  7.             "type""platform"  
  8.         },  
  9.         "Microsoft.AspNetCore.Server.IISIntegration""1.0.0-rc2-final",  
  10.         "Microsoft.AspNetCore.Mvc""1.0.0-rc2-final",  
  11.         "Microsoft.Extensions.DependencyInjection.Abstractions""1.0.0-rc2-final",  
  12.         "Microsoft.AspNetCore.Server.Kestrel""1.0.0-rc2-final",  
  13.         "Microsoft.Extensions.Configuration.EnvironmentVariables""1.0.0-rc2-final",  
  14.         "Microsoft.Extensions.Configuration.Json""1.0.0-rc2-final",  
  15.         "Microsoft.Extensions.Configuration.UserSecrets""1.0.0-rc2-final",  
  16.         "Microsoft.AspNetCore.Diagnostics""1.0.0-rc2-final",  
  17.         "Microsoft.AspNetCore.Razor.Tools":  
  18.         {  
  19.             "version""1.0.0-preview1-final",  
  20.             "type""build"  
  21.         },  
  22.         "Microsoft.EntityFrameworkCore.Tools":  
  23.         {  
  24.             "version""1.0.0-preview1-final",  
  25.             "type""build"  
  26.         },  
  27.         "Microsoft.VisualStudio.Web.CodeGeneration.Tools":  
  28.         {  
  29.             "version""1.0.0-preview1-final",  
  30.             "type""build"  
  31.         },  
  32.         "Microsoft.VisualStudio.Web.CodeGenerators.Mvc":  
  33.         {  
  34.             "version""1.0.0-preview1-final",  
  35.             "type""build"  
  36.         },  
  37.         "Microsoft.AspNetCore.StaticFiles""1.0.0-rc2-final"  
  38.     },  
  39.     "frameworks":  
  40.     {  
  41.         "netcoreapp1.0":  
  42.         {  
  43.             "imports": [  
  44.                 "dotnet5.6",  
  45.                 "dnxcore50",  
  46.                 "portable-net45+win8"  
  47.             ]  
  48.         }  
  49.     },  
  50.     "tools":  
  51.     {  
  52.         "Microsoft.AspNetCore.Razor.Tools":  
  53.         {  
  54.             "version""1.0.0-preview1-final",  
  55.             "imports""portable-net45+win8+dnxcore50"  
  56.         },  
  57.         "Microsoft.AspNetCore.Server.IISIntegration.Tools":  
  58.         {  
  59.             "version""1.0.0-preview1-final",  
  60.             "imports""portable-net45+win8+dnxcore50"  
  61.         },  
  62.         "Microsoft.EntityFrameworkCore.Tools":  
  63.         {  
  64.             "version""1.0.0-preview1-final",  
  65.             "imports": [  
  66.                 "portable-net45+win8+dnxcore50",  
  67.                 "portable-net45+win8"  
  68.             ]  
  69.         },  
  70.         "Microsoft.Extensions.SecretManager.Tools":  
  71.         {  
  72.             "version""1.0.0-preview1-final",  
  73.             "imports""portable-net45+win8+dnxcore50"  
  74.         },  
  75.         "Microsoft.VisualStudio.Web.CodeGeneration.Tools":  
  76.         {  
  77.             "version""1.0.0-preview1-final",  
  78.             "imports": [  
  79.                 "portable-net45+win8+dnxcore50",  
  80.                 "portable-net45+win8"  
  81.             ]  
  82.         }  
  83.     },  
  84.     "publishOptions":  
  85.     {  
  86.         "include": [  
  87.             "wwwroot",  
  88.             "Views",  
  89.             "appsettings.json",  
  90.             "web.config"  
  91.         ]  
  92.     },  
  93.     "buildOptions":  
  94.     {  
  95.         "emitEntryPoint"true,  
  96.         "preserveCompilationContext"true  
  97.     },  
  98.     "runtimeOptions":  
  99.     {  
  100.         "gcServer"true  
  101.     },  
  102.     "scripts":  
  103.     {  
  104.         "postpublish": ["dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%"]  
  105.     }  
  106. }  
Now save the file so it will restore the required packages for your app.

xproj File Changes

Unload your project first and then right-click on it to edit the project file. We will need to manually change some configuration in the file because your existing xproj file has references to the old Beta 8 tools which uses DNX. In this case we will need to change the string "DNX\Microsoft.DNX.Props" to "DotNet\Microsoft.DotNet.Props". Basically the “DNX” reference will now be changed to “DotNet”. So your import tag should now look like this:
  1. <ImportProject="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props"Condition="'$(VSToolsPath)' != ''" />  
You also need to change the string "DNX\Microsoft.DNX.targets" to "DotNet.Web\Microsoft.DotNet.Web.Props".Your other import tag would now look like this:
  1. <ImportProject="$(VSToolsPath)\DotNet.Web\Microsoft.DotNet.Web.targets"Condition="'$(VSToolsPath)' != ''" />  
You may also want to change the BaseIntermediateOutputPath and OutputPath to:
  1. <BaseIntermediateOutputPathCondition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>  
  2. <OutputPathCondition="'$(OutputPath)'=='' ">.\bin\</OutputPath>  
And finally, add a TargetFrameworkVersionbelow the OutputPath element:
  1. <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>  
Now save your .xproj file and then reload your project in Visual Studio.

Code Changes

Adding Program.cs File

Adding this class is not really a requirement because you can just add an entry point to your existing startup.cs file. But just to follow the new project templates for RC2, I’ve decided to generate a separate file called “Program.cs” to put our main entry point – the static void Main() method.

The Program.cs file contains the Main method of an ASP.NET Core RC2 app, which is responsible for configuring and running the app. Here’s how it would look like:
  1. using System.IO;  
  2. usingMicrosoft.AspNetCore.Hosting;  
  3. namespace MVC6Demo  
  4. {  
  5.     publicclassProgram  
  6.     {  
  7.         publicstaticvoid Main(string[] args)  
  8.         {  
  9.             var host = newWebHostBuilder()  
  10.                 .UseKestrel()  
  11.                 .UseContentRoot(Directory.GetCurrentDirectory())  
  12.                 .UseIISIntegration()  
  13.                 .UseStartup < Startup > ()  
  14.                 .Build();  
  15.             host.Run();  
  16.         }  
  17.     }  
  18. }  
Modifying Startup.cs

Here are the changes for my Startup.cs file:
  1. public Startup(IHostingEnvironmentenv)  
  2. {  
  3.     var builder = newConfigurationBuilder()  
  4.         .SetBasePath(env.ContentRootPath);  
  5.     builder.AddEnvironmentVariables();  
  6.     Configuration = builder.Build();  
  7. }  
  8. publicIConfigurationRoot Configuration  
  9. {  
  10.     get;  
  11. }  
Renaming Namespaces

Since our project.json package references was changed then we also need to change the namespaces that are being used. For example do a “find and replace” and then change “using Microsoft.AspNet” to “using Microsoft.AspNetCore”. Following are the affected changes in my project:
  1. usingMicrosoft.AspNetCore.Builder;  
  2. usingMicrosoft.AspNetCore.Hosting;  
  3. usingMicrosoft.AspNetCore.Mvc;  
You also need to change the namespace reference of the following:

"usingMicrosoft.Framework.DependencyInjection" > "using Microsoft.Extensions.DependencyInjection"
"Microsoft.Data.Entity" > "Microsoft.EntityFrameworkCore"


launchSettings.json Changes

Under Properties, open up the launchSettings.json file. Find the “web” section and replace it with the new “DotNet” stuff below:
  1. "MVC6Demo":  
  2. {  
  3.     "commandName""Project",  
  4.     "launchBrowser"true,  
  5.     "launchUrl""http://localhost:5000",  
  6.     "environmentVariables":  
  7.     {  
  8.         "ASPNETCORE_ENVIRONMENT""Development"  
  9.     }  
  10. }  
The “ASPNETCORE_ENVIRONMENT” replaces the old “Hosting:Environment” and is the new environment variable for RC2.

You may also want to change the port number used in IIS Express. In my case I have this configuration:
  1. "iisSettings":  
  2. {  
  3.     "windowsAuthentication"false,  
  4.     "anonymousAuthentication"true,  
  5.     "iisExpress":  
  6.     {  
  7.         "applicationUrl""http://localhost:50295/",  
  8.         "sslPort": 0  
  9.     }  
  10. },  
ViewComponent Changes

InvokeAsync now takes anonymous object instead of separate parameters. With this change you would need call @Component.InvokeAsync(“Name of View Component”,<params>) from your View. In my previous example I needed to change this call:
  1. @awaitComponent.InvokeAsync("HeroList""strength")  
To this:
  1. @awaitComponent.InvokeAsync("HeroList"new { type = "strength" })  
Here’s a sample screenshot of the converted ASP.NET MVC 6 App to ASP.NET Core MVC RC2:



I’ve uploaded the converted project so you will have a clearer view about the changes and to test it yourself. So go ahead and download it.

I know there are a few changes that I haven’t covered in this article because I’m just basing a simple project to convert. To learn more about the RC2 conversion please refer the following articles below: