Upgrading vNext MVC6 Apps From Beta4 to Beta5
It’s been a while, but my last few sprints have been focused on working with ASP.NET 5 MVC6, namely evaluating what is going on in order to protoype an app front-end. Working with Beta versions is definitely challenging – there are plenty of moving parts and a lack of documentation. Fortunately, the term “community” is one we can apply more to what is going on with Microsoft’s iniciative. I’ve been pretty much googling stuff, deducing concepts, and hogging the Jabber #AspNetvNext chat room, where, fortunately, I’m getting answers I need.
I started developing the prototype in Beta4, and decided to migrate to Beta5 before starting to add even more parts to the project. Unfortunately, upgrading isn’t the easiest thing in the world, but it is possible.
Your runtime environment should be one that can support Beta5 correctly. At this time, the latest is Beta6-10383. To upgrade, you can run in the command line window:
@powershell -NoProfile -ExecutionPolicy unrestricted -Command "&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}"
This will update dnvm itself, if you are still in Beta4. As of the beta5 or 6 version, a self-update command is available.
With dnvm updated, you should upgrade the dnu versions.
dnvm upgrade
should pull and install the most recent stable dnu. You can indicate a specific version also:
dnvm install 1.0.0-beta5-11904
or
dnvm install 1.0.0-beta5-11904 -r coreclr
if you want to choose/specify the clr type. You can also pull the most recente beta build available using
dnvm upgrade -Unstable
In your solution’s global.json, update the sdk version value:
"sdk": {<br /> "version": "1.0.0-beta5-11904"<br /> }
At this time, you can update package refs in your projects to Beta5 versions. One thing to consider, though, is that from Beta4 to Beta5, a lot of changes have occurred, especially in the namespaces for some class. For instance, pretty much every package set now has an *.Abstractions
package with base classes and interfaces, separated from their implementations. I would at this point recommend excluding as many projects as it would make sense to and to update gradually, traversing the dependency chain. This is simply to reduce the amount of focus required to analyse output errors.
The main NuGet feed contains a large set of packages, but if you want to try using the latest and greatest, you can pull from the myGet feed. In order to do so, at the same level as your global.json
and .sln
file, add a .nuget/
folder and a NuGet.config file (similar to previous solution types). Add the following :
`
`
I prefer having this in the solution, and committed to source control, as the entire team can share this definition in the solution context AND you won’t have to manually configure VS to use the repository (which would make it available to every solution you use, which you may or may not want).
Alot of things are changing, so some car is required, and code will require updates. The most common change that affected me were namespace changes (as mentioned in https://github.com/aspnet/Announcements/issues/14). Pretty much all of the repos have some Abstractions namespace associated to it, now. That’s actually a pretty good thing , in my opinion. If you are not tied to a specific implementation of abstract class or interface, the only reference you are required to have in class libs is the abstractions package. That makes use of DI more straight foward in the application project, which would be where the actual implementation is referenced. Other than there, you can always program against the abstraction and Mock as you wish in tests.
Some common abstraction refs I required where:
<td>
Microsoft.Framework.Caching
</td>
<td>
IExperationTrigger
</td>
<td>
Microsoft.Framework.FileProviders
</td>
<td>
IFileInfo, IDirectoryContents
</td>
<td>
Microsoft.Framework.DependencyInjection
</td>
<td>
IServiceCollection
</td>
<td>
Microsoft.Framework.Runtime
</td>
<td>
ILibraryManager
</td>
<td>
Microsoft.AspNet.Http
</td>
<td>
IApplicationBuilder
</td>
Configuration classes have changes also (https://github.com/aspnet/Announcements/issues/25 , https://github.com/aspnet/Announcements/issues/26). There is a preference towards using ConfigurationModel
classes / packages, to tie into the OptionsModel
, instead of the previous Configuration (though configuration builder is in Configuration). Configuration can be loaded into IOption
objects in DI by using the following code:
`var applicationEnvironment = services.BuildServiceProvider().GetRequiredService(); var configurationPath = Path.Combine(applicationEnvironment.ApplicationBasePath, “config.json”);
The path to the config file should now be an absolute path as mentioned in https://github.com/aspnet/Announcements/issues/13
If you use _GlobalImport.cshtml
for your views, the file name convention has changed to search for _ViewImports.cshtml
(plural) as mentioned in https://github.com/aspnet/Announcements/issues/27 . That file should therefore be renamed.
For some unexplained reason, I was having trouble using Use* extension methods on IApplicationBuilder such as UseStaticFiles and UseCookieAuthentication. For some odd reason, the runtime shouldn’t load the UseMiddleware<>() method those extensions use.
System.MissingMethodException<br /> Método não encontrado: 'Microsoft.AspNet.Http.Authentication.SignInContext Microsoft.AspNet.Authentication.AuthenticationHandler.get_SignInContext()'.
For some reason some packages were not playing nice. The workarounds I used:
For UseStaticFiles()
, I just used what the extension actually does:
//app.UseStaticFiles();<br /> app.UseMiddleware<StaticFileMiddleware>(new StaticFileOptions());
For UseCookieAuthentication()
, using Beta6
packages for Microsoft.AspNet.Authentication
and Microsoft.AspNet.Authentication.Cookies
solved the problem.