Migration zu ASP.NET Core RC2
Published on Friday, May 27, 2016 6:53:35 AM UTC in Programming
Der Umfang der Dokumentation zur Migration von ASP.NET Core RC1 (ehemals: ASP.NET 5 RC1) zu ASP.NET Core RC2 lässt schon vermuten, dass das Upgrade nicht unbedingt ein trivialer Schritt ist. Gute Einstiegspunkte finden sich bei "Migrating from DNX to .NET Core CLI" und "Migrating from ASP.NET 5 RC1 to ASP.NET Core". Um nicht wieder und wieder in dieselben Fallen zu tappen, habe ich mir diese Checkliste erstellt, wenn es um das Umstellen von Projekten geht.
0. Vorbereitung und Installation
Zunächst einmal gilt es, die Überreste des alten ASP.NET 5 RC1 vom System zu entfernen, was theoretisch wie gewohnt über die Systemsteuerung funktioniert. Leider war der ursprüngliche Installer eine EXE-Datei statt eines MSI, so dass Windows diesen nicht automatisch weggesichert hat. Wer den Installer zwischenzeitlich bewusst oder unterbewusst (Browser Cache!) gelöscht hat, kann die Deinstallation nicht durchführen. Man muss zunächst den alten Installer wieder herunterladen und der Deinstallationsroutine mitteilen, wo er liegt (GitHub Issue hierzu). Download-Links zum Installer:
- RC1 Update 1: AspNet5.ENU.RC1_Update1.exe
- RC1 Update 1 als Teil der VS Developer Tools: AspNet5.ENU.RC1_Update1_KB3137909.exe
Nach der Deinstallation kann man dann RC2 installieren. Am einfachsten geht das über den Installer des Tooling Preview 1 für Visual Studio 2015, der auch gleich das .NET Core SDK mitinstalliert.
Was man eher selten als Hinweis findet ist, dass man auch eine Vorab-Version des NuGet Package Managers installieren soll, zum aktuellen Zeitpunkt ist das die Version 3.5 Beta.
Generell empfehle ich, vor der Installation auf http://dot.net vorbeizusehen und die dort aktuellen Links abzugreifen, da sie sich ggfs. zwischenzeitlich geändert haben könnten.
1. project.json
Das Aufräumen kann beginnen :). Ein grundsätzlich guter Ansatz ist, zunächst ein neues, leeres RC2-Projekt zu erstellen, damit man eine Vergleichsmöglichkeit hat und einfacher z.B. Versionsnummern von Dependencies u.ä. übernehmen zu können, statt diese mühsam heraussuchen und manuell eintippen zu müssen.
- Ersetze
compilationOptions
mitbuildOptions
. Wichtig ist die Option"emitEntryPoint": true
darin, sowie bei der Verwendung von On-the-Fly zu kompilierenden Dateien wie bei MVC (Razor Views) die Options"preserveCompilationContext": true
- Entferne den
command
-Knoten vollständig. Das Konzept gibt es in dieser Form nicht mehr. - Entferne
exclude
-Einträge bzw. verschiebe sie hin zubuildOptions/compile/exclude
- Entferne
publishExclude
-Einträge bzw. verschiebe sie hin zupublishOptions/exclude
- Ersetze alle rc1-final-Einträge in
dependencies
mit dem Pendant rc2-final. Da es auch Umbenennungen gab und teilweise Pakete nicht mehr referenziert werden müssen (Tag Helpers), tut man sich am einfachsten, wenn man diedependencies
aus einem neuen, leeren Projekt übernimmt. - Ersetze alle Framework-Monikers mit den neuen/richtigen. Also etwa
dnx461
/dnx451
mitnet461
/net451
etc. - Füge einen neuen
tools
-Eintrag hinzu; diesen übernimmt man ebenfalls am besten aus einem neuen, leeren Projekt. - Füge
runtimeOptions
hinzu. Insbesondere wichtig für ASP.NET Core-Anwendungen ist der Eintrag"gcServer": true
; der zweite Eintrag sollte"gcConcurrent": true
sein.
Das war es auch schon mit der grundlegenden Projektkonfiguration.
2. launchsettings.json
Hier befinden sich die Einträge, die Visual Studio zum Starten (bzw. Debuggen) der Anwendung bereitstellt. Die Datei ist etwas versteckt im Unterordner "Properties" zu finden. Da das Konzept der Kommandos in der project.json in der bisherigen Form abgeschafft wurde, muss der dort vorhandenen Eintrag web
entweder entfernt oder durch das eingebaute Kommando project
ersetzt werden. Etwa so:
"BeliebigerName": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
3. Startup.cs
Da am Konzept des Bootstrappings am meisten verändert wurde, sind viele Teile der Startup.cs betroffen. Insbesondere:
- Entferne die statische
Main
-Methode. - Entferne Aufrufe zur
IISPlatformIntegration
aus derConfigure
-Methode. - Ersetze alle
AspNet
-Usings mitAspNetCore
. - Ersetze
IApplicationEnvironment.ApplicationBasePath
mitIHostingEnvironment.ContentRootPath
. - Ersetze die Fluid-Variante
ReloadOnChanged()
der Konfiguration mit dem ArgumentreloadOnChange
in der MethodeAddJsonFile
. - Ersetze
.AddInstance()
-Aufrufe auf derServiceCollection
mit.AddSingleton()
. - Füge
.SetBasePath(hostingEnvironment.ContentRootPath)
zurConfigurationBuilder
-Aufrufkette hinzu.
Der eigentliche Einstiegspunkt der Anwendung sollte der Übersichtlichkeit halber in eine separate Program.cs wandern:
4. Program.cs (neu)
Bei ASP.NET Core RC2-Anwendungen handelt es sich um gewöhnliche Konsolenprogramme, deren Main-Methode das eigentliche Bootstrapping vornimmt. Ein vollständiges Beispiel dieser Methode sieht etwa so aus:
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
}
5. appsettings.json
Die Benennung und Reihenfolge der Log-Levels hat sich verändert. Der frühere Eintrag Verbose
wurde umbenannt in Trace
und ist jetzt in der Ausführlichkeit unterhalb von Debug
angesiedelt. Ggfs. sind also Einträge hier zu korrigieren oder abzuändern.
6. Projekt-Eigenschaften
Aus Kompatibilitätsgründen mit anderen Plattformen wurde die Benennung der Umgebungsvariablen angepasst. Statt des :
wird nun ein Underscore _
zur Trennung verwendet. Gleichzeitig wurde die Bennenung vereinheitlicht; Variablen beginnen nun mit ASPNETCORE
.
Daraus ergibt sich unmittelbar, dass man in den Projekt-Eigenschaften den bisherigen Eintrag Hosting:Environment
umbennen sollte in ASPNETCORE_ENVIRONMENT
.
7. web.config
Die Datei web.config wandert vom Unterordner wwwroot (bzw. dem für das Projekt abweichend konfigurierten Root-Ordner) ins Stammverzeichnis. Der Inhalt muss sich auf Grund der geänderten Integration mit IIS ändern zu:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
</handlers>
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
</system.webServer>
</configuration>
8. Suchen und Ersetzen
Nachdem man nun die chirurgischen Eingriffe hinter sich hat, kann man mit der großen "Suchen und Ersetzen"-Keule weitermachen.
- Ersetze global alle
using Microsoft.AspNet.
-Strings mitusing Microsoft.AspNetCore.
- Ersetze global auch alle Namespace-Verweise in (Razor-)Views (
Microsoft.AspNet.
) mit dem neuen Namespace (Microsoft.AspNetCore.
) - Ersetze global alle synchronen Aufrufe von
ViewComponents
mit dem asynchronen Gegenstück (siehe https://docs.asp.net/en/latest/migration/rc1-to-rc2.html#viewcomponents-changes) - Ersetze global in allen Validation Summary-Elementen
ValidationSummary.All
mit dem WertAll
9. Class Libraries überarbeiten
Die bisherigen "Package"-Class-Libraries funktionieren weiterhin. Allerdings muss man auch hier die unter 1. beschriebenen Änderungen an der project.json durchführen, insbesondere die Anpassung der Framework Monikers, falls nötig, und natürlich die Aktualisierung der Dependencies.
10. Tooling
Momentan hat insbesondere ReSharper größere Probleme mit ASP.NET Core RC2 (Beispiel-Issue bei JetBrains). Am nervigsten ist, dass die Razor-Views teilweise komplett kaputt sind und Dutzende "False Positives" verursachen bzw. ReSharper mit ständigen Vorschlägen stört, welche Referenzen man doch bitte hinzufügen sollte. Zur Lösung gibt es zwei Möglichkeiten. Entweder man schaltet die Razor-Unterstützung von ReSharper ab:
Oder aber man wagt sich als Bleeding Edge-Adopter daran, die gestern (26.05.) veröffentlichte EAP 1 von ReSharper 2016.2 zu installieren. Meiner Erfahrung nach repariert sie diese Fehler tatsächlich recht zuverlässig.
Ansonsten empfehle ich noch, nach der Migration kurz Visual Studio zu schließen, die .vs
-Ordner des Projekts zu löschen, und dann die Solution neu zu öffnen - ich hatte bei zwei Versuchen ansonsten teils komische Effekte, die nach einem Neustart von Visual Studio aber verschwunden waren.
Danach bleibt nur noch, alle verbleibenden Compile-Fehler zu beheben, sollten noch welche übrig sein ;).
Known Issues
Das ValidationSummary
-Control konnte ich bisher nicht zuverlässig in Kombination mit asynchronen ViewComponents
zum Laufen bekommen. Ich erhalte reproduzierbare NullReferenceExceptions
, die mich stark an ein früheres Problem mit derselben Komponente erinnern.
Viel Erfolg!
Tags: ASP.NET Core