Upgrading from ASP.NET 5 Beta 7 to Beta 8


officetoolsIf you’ve been following along, you know by now that I’m investing my time into learning ASP.NET 5. Now that the ASP.NET team have released a new version, let me help you move your code to the new version.

The update this time includes some simple package changes but also some major API changes. I am sure I can’t cover them all here, but hopefully I’ll help you avoid the major ones.

Let’s walk through the changes I am doing when upgrading a project:

project.json

  • Replace all the references from .beta7 to .beta8.
  • Replace “Microsoft.AspNet.Server.IIS” with “Microsoft.AspNet.IISPlatformHandler” for the new IIS integration.
  • Replace “Microsoft.AspNet.Server.WebListener” with “Microsoft.AspNet.Server.Kestrel” as they are moving us to the higher performing Kestrel server (this is optional, if you want to stay with the http.sys based WebListener, it’s fine).
  • Change the ‘web’ command in “commands” section to use “Microsoft.AspNet.Server.Kestrel” with no arguments.

For example:

  "dependencies": {
    "Microsoft.AspNet.Mvc": "6.0.0-beta8",
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-beta8",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-beta8",
    "Microsoft.AspNet.StaticFiles": "1.0.0-beta8",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta8",
    "Microsoft.Framework.Configuration.Json": "1.0.0-beta8",
    "EntityFramework.Core": "7.0.0-beta8",
    "EntityFramework.SqlServer": "7.0.0-beta8",
    "EntityFramework.Commands": "7.0.0-beta8",
    "Microsoft.Framework.Logging.Debug": "1.0.0-beta8",
    "Microsoft.AspNet.Identity": "3.0.0-beta8",
    "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-beta8",
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta8"
  },

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel",
    "ef": "EntityFramework.Commands"
  },

Startup.cs

  • In the constructor of the Startup class, you’ll want to change the way you set up the configuration by using SetBasePath instead of the old way of using the constructor:

Old:

public Startup(IApplicationEnvironment appEnv)
{
  var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
    .AddJsonFile("config.json")
    .AddEnvironmentVariables();

  Configuration = builder.Build();
}

New:

public Startup(IApplicationEnvironment appEnv)
{
  var builder = new ConfigurationBuilder()
    .SetBasePath(appEnv.ApplicationBasePath)
    .AddJsonFile("config.json")
    .AddEnvironmentVariables();

  Configuration = builder.Build();
}
  • Change the error page calls to use Exception instead:

Old

if (env.IsDevelopment())
{
  app.UseBrowserLink();
  app.UseErrorPage();
  app.UseDatabaseErrorPage();
}
else
{
  // Add Error handling middleware which catches all application specific errors and
  // sends the request to the following path or controller action.
  app.UseErrorHandler("/Home/Error");
}

New

if (env.IsDevelopment())
{
  app.UseBrowserLink();
  app.UseDeveloperExceptionPage();
  app.UseDatabaseErrorPage();
}
else
{
  // Add Error handling middleware which catches all application specific errors and
  // sends the request to the following path or controller action.
  app.UseExceptionHandler("/Home/Error");
}

  • Most configurations inside the configuration of options have moved from specific calls in the ConfigureServices method to passing in a lambda in the Configure. For example the Facebook Auth configuration:

Old:

services.Configure<FacebookAuthenticationOptions>(options =>
{
  options.AppId = Configuration["Authentication:Facebook:AppId"];  
  options.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
});

New:

app.UseFacebookAuthentication(options => 
{
  options.AppId = Configuration["Authentication:Facebook:AppId"];
  options.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
});

  • Lastly, if you’re using IIS to serve your project, you’ll need to opt into the IIS Handler in the Configure method:
public void Configure(IApplicationBuilder app)
{
  app.UseIISPlatformHandler();
}

Deleted Files

  • Remove the hosting.ini file from the project as it’s not used any longer.

Controllers

  • In your controllers, you’ll want to change any reference to Controller.Context to Controller.HttpContext to better align with older versions of ASP.NET.

An Odd Bug

I did find one bug that isn’t quite new but has been exposed by the switch to Kestrel as the web server. In Beta 8 and later, Kestrel is now being used even in IIS. The problem is that there is a bug that was exposed (and probably won’t be fixed until RC1). The bug is that route parameters aren’t UrlEncoded. For example, if you’re calling an API via “http://localhost:5000/api/trip/US%20Trip/stops” the “US Trip” is being passed into the controller as “US%20Trip”. Work around is easy but annoying:

[HttpGet("")]
public JsonResult Get(string tripName)
{
  var decodedTripName = WebUtility.UrlDecode(tripName);
  // ...
}

I am sure I missed some things, but hopefully this will get you started!

Finally, some JSON for you:

{
  "selfServing": {
    "course": "Building a Web App with ASP.NET 5, MVC 6, Entity Framework 7 and AngularJS",
    "url": "http://shawnw.me/learnaspnet5
  }
}




Application Name WilderBlog Environment Name Production
Application Ver 1.1.0.0 Runtime Framework .NETCoreApp,Version=v1.1
App Path D:\home\site\wwwroot Runtime Version .NET Core 4.6.25211.01
Operating System Microsoft Windows 6.2.9200 Runtime Arch X86