Cover

Getting Ready for ASP.NET Core RC2

May 13, 2016
No Comments.

I’m starting to play with the Preview of RC2 (nightly builds). It’s not time to do it for most people, but I’m trying to prepare for the update to my ASP.NET Core RC1 course on Pluralsight.

I have a couple of small library projects that I created when I build the new website. Since they are both pretty small and have xUnit testing, I thought it might be a good place to start.

An Example

I started by branching the projects so that I could merge them after RC2 shipped. The one I’ll walk you through is the MetaWeblog project. This is a small middleware for ASP.NET Core to support the Meta Weblog API to support Windows Live Writer (and other tools) for writing your blog items. You can see the comparison between the master and the RC2 branch here:

https://github.com/shawnwildermuth/MetaWeblog/compare/master…RC2

Let’s see what it took to get there…

Getting the RC2 Bits

First thing you need is to get the RC2 bits. There are two installers that I get every time they are updated. Go to the CLI repository on Github and you’ll see installers for “.NET Core Installer” and “.NET Core SDK Installer”:

https://github.com/dotnet/cli#installers-and-binaries

The current version is 1.0.0-preview1-002702. You have to uninstall and reinstall every time. Don’t just install over the old version (you’ll get two versions). Once you have these, you can confirm you have the right bits installed by opening a console and typing ‘dotnet --version’:

image

Note that you don’t need to install the runtime like you did with RC1. It’s just another dependency of the project, but I’ll get to that in a minute.

Changing the project.json

For the project changes, you can just use Visual Studio Code or Visual Studio (or any text editor). Visual Studio will *not* work for actually building it, we’re going to do it all at the command-line.

There are several changes to the project.json file. Let’s go through them one at a time:

First, if you’re using properties about the nuget packages in your project.json (e.g. licenseUrl, tags, repository, etc.), you’ll need to move it into a packOptions node as shown below (RC1 is on the left, and RC2 is on the right)

// RC1 Version 
{
  "version": "0.4.0-beta-*",
  "description": "A MetaWeblog API implementation for ASP.NET 5 (DXCore and DNX451).",
  "authors": [ "shawn" ],
  "tags": [ "xmlrpc", "metablogapi", "blogs" ],
  "projectUrl": "http://github.com/shawnwildermuth/metaweblog",
  "licenseUrl": "",


// RC2 Version
{
  "version": "0.4.0-rc2-*",
  "description": "A MetaWeblog API implementation for ASP.NET Core.",
  "authors": [ "shawn" ],
  "packOptions": {
    "tags": [ "xmlrpc", "metablogapi", "blogs" ],
    "projectUrl": "http://github.com/shawnwildermuth/metaweblog",
    "licenseUrl": "",
    "repository": {
      "type": "git",
      "url": "git://github.com/shawnwildermuth/metaweblog"
    }
  }

Next, you’ll need to add the runtime as a dependency. You do this by adding it like so:

"dependencies": {
  "Microsoft.NETCore.App": {
    "type": "platform",
    "version": "1.0.0-rc2-*"
  },

This is a dependency to the actual runtime. Now the runtime is just a dependency! That’s an interesting idea. Team members have stated publically that they might allow for a dnvm-like experience of downloading machine-level runtimes, but not in the RC2 timeframe.

Next rename all the Microsoft.AspNet.* references to Microsoft.AspNetCore.*:

  "dependencies": {
    "Microsoft.NETCore.App": {
      "type": "platform",
      "version": "1.0.0-rc2-*"
    },
    "Microsoft.AspNetCore.Http.Abstractions": "1.0.0-rc2-*",
    "Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0-rc2-*",
    "Microsoft.Extensions.Logging.Abstractions": "1.0.0-rc2-*"
  },

You can remove the “commands” section entirely, there is a new way to do that that I’ll show you in a minute.

Finally, you’ll need to change the “frameworks” section. Remove all the frameworks you’re working with and replace it like so:

"frameworks": {
  "netcoreapp1.0": {
    "imports": [ "dotnet5.4" ]
  }
}

The “netcoreapp1.0” is the new designation for dxcore apps. You could also add “net46” or “dnx46” to use the desktop .NET framework but so far that isn’t working, so I’m sticking with the dxcore stuff until RC2 ships. I’m still trying to understand the whole imports section, but essentially it’s a hint about what framework PCL level support you need. Now that we’ve made that change, let’s get the project built to see what you have to change.

Restoring the Packages

In the console, go to the root of the directory with the project.json and use dotnet restore to get the new nuget packages. This will actually fail because the sources for nuget are only the public ones and we’re using the nightly builds. If you’re not sure if it failed, re-run the command only showing the minimal output which is easier to see the errors “dotnet restore –v Minimal”:

Errors in D:\projects\MetaWeblog\src\WilderMinds.MetaWeblog\project.json
    Unable to resolve 'System.Xml.XDocument (>= 4.0.11-rc2)' for '.NETCoreApp,Version=v1.0'.
    Unable to resolve 'Microsoft.NETCore.App (>= 1.0.0-rc2)' for '.NETCoreApp,Version=v1.0'.
    Unable to resolve 'System.Reflection.Extensions (>= 4.0.1-rc2)' for '.NETCoreApp,Version=v1.0'.
    Unable to resolve 'System.Collections (>= 4.0.11-rc2)' for '.NETCoreApp,Version=v1.0'.
    Unable to resolve 'Microsoft.Extensions.Logging.Abstractions (>= 1.0.0-rc2)' for '.NETCoreApp,Version=v1.0'.
    Unable to resolve 'Microsoft.Extensions.DependencyInjection.Abstractions (>= 1.0.0-rc2)' for '.NETCoreApp,Version=v1.0'.
    Unable to resolve 'Microsoft.AspNetCore.Http.Abstractions (>= 1.0.0-rc2)' for '.NETCoreApp,Version=v1.0'.

What we need is to add the new sources for nuget. You could change your machine level nuget.config but I’d rather be cleaner than that, so I create one in the /src directory of my project (the parent of both the projects):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="dotnet.cli" value="https://dotnet.myget.org/F/dotnet-cli/api/v3/index.json" />
    <add key="dotnet.core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
    <add key="RC2" value="https://www.myget.org/F/aspnetvnext/api/v3/index.json" />
    <add key="xunit" value="https://www.myget.org/F/xunit/" />
  </packageSources>
</configuration>

This includes the RC2 builds, the DotNet.Core builds, the DotNet.CLI builds and xunit’s nightly builds. These are additive to the nuget.config and is a great way to isolate these changes. Once you’ve added this, try doing “dotnet restore –v Minimal” again and see it work (probably).

Building the Project

To build the project, just type “dotnet build”. This will attempt to build the project. The nature of the errors you’ll see will depend a lot on your project. For mine, I had to change any namespace changes from Microsoft.AspNet.* to Microsoft.AspNetCore.* as well as any actual API changes. Much of the code was fine, but anything related to integrating with ASP.NET is likely to see some level of fixes you’ll need to make.

Making the Tests Work

Once I had the project building cleanly, I had to make the tests work. The changes I mentioned earlier in the** project.json** still apply to the test project with some additional fixes. First, I needed to change the xunit and xunit runner:

// RC1 Version
"dependencies": {
  "xunit": "2.1.0-*",
  "xunit.runner.dnx": "2.1.0-*",
  
// RC2 Version
"dependencies": {
  "Microsoft.NETCore.App": {
    "type": "platform",
    "version": "1.0.0-rc2-*"
  },
  "xunit": "2.1.0-rc2-*",
  "dotnet-test-xunit": "1.0.0-rc2-*",

Note that we’re changing the **xunit **version to the rc2 version, but more importantly, we’re replacing the xunit.runner.dnx with a new **dotnet-test-xunit **project that’s being maintained by Microsoft at this time.

Next, we need to remove the ‘test’ command and replace it with a simple ‘testRunner’ designation that tells dotnet to use it as a command:

// RC1 Version
  "commands": {
    "test": "xunit.runner.dnx"
  },

// RC2 Version
  "testRunner": "xunit",

Lastly, we need to add the framework like before, but that imports needs an additional line to specify that it is a PCL (xunit is a PCL so this helps it figure out how to host it in the runtime):

"frameworks": {
  "netcoreapp1.0": {
    "imports": [
      "dotnet5.4",
      "portable-net451+win8"
    ]
  }
}

This line is important to getting xunit working. You can now use “dotnet restore” to get the new dependencies.

I found that if I then try and run “dotnet test” to run the tests, that it failed because of a failed build. The reason was that one of the parts of the test runner I was using had changed: TestServer.

I was using TestServer to help test the middleware I built but it changed. The old version just let you supply a configure and configure services lambda:

TestServer GetServer()
{
  return TestServer.Create(app =>
  {
    app.UseMetaWeblog("/livewriter");
  }, svcs =>
  {
    svcs.AddMetaWeblog<TestMetaWeblogService>();
  });
}

But the new version required you use the new WebHostBuilder class to do it like RC2 does when it starts a new web server:

TestServer GetServer()
{
  var bldr = new WebHostBuilder()
     .Configure(app => app.UseMetaWeblog("/livewriter"))
     .ConfigureServices( svcs => svcs.AddMetaWeblog<TestMetaWeblogService>());
  return new TestServer(bldr);
}

You’ll likely see other code changes that need to be made. But after this change (and namespaces fixes) I was able to run my tests with “dotnet test”:

Untitled

Hope this helps. Lots of this is likely to change as RC2 approaches but if you’re like me and want to play with what’s coming, I’m hoping you find this useful!