ASP.NET Core 1.0 – ein Portierungsversuch

11. Mai 2016

Das sich derzeit in Entwicklung befindliche ASP.NET Core 1.0 soll auch auf Linux und OS X laufen können. Wir wollten es wissen und haben deshalb einen Portierungsversuch unserer bestehenden Web API nach ASP.NET unternommen.

Vorgehensweise
Die Portierung war in zwei Schritten angedacht: Zunächst Umstellung nach ASP.NET Core 1.0, danach Portierung nach .NET Core 1.0. Da ASP.NET Core auch auf dem vollständigen .NET Framework laufen kann, wollte ich zunächst einmal die ganze API auf ASP.NET Core umstellen, bevor ich es dann mit dem neuen .NET Core aufnehme. Denn bei beiden Schritten erwartete ich Kompatibilitätsprobleme.

Da nur bestimmte Teile des bestehenden .NET Frameworks nach .NET Core portiert wurden, bestand in unserem Fall die Gefahr, dass auch Teile unserer API aus Inkompatibilitätsgründen nicht nach .NET Core portiert werden können. Des Weiteren werden von uns derzeit auch externe Programmbibliotheken, z. B. für die Kommunikation mit CRM, verwendet, die womöglich ebenfalls nicht unter .NET Core lauffähig sind.

In der Visual Studio-Solution unserer API befinden sich zwei Projekttypen – Web API-Projekte und Klassenbibliotheken. Der Ansatz, zunächst eine neue Solution zu erstellen, um anschließend die bestehenden Class Libraries einfach zu referenzieren, stand uns nicht zur Verfügung, da für ASP.NET Core eine komplett neue Vorlage für Klassenbibliotheksprojekte verwendet werden muss. In diesen Projekten kann man dann nämlich die zu unterstützenden Frameworks einstellen (.NET Core oder .NET Framework) und somit theoretisch für alle Plattformen gleichzeitig entwickeln.

Demzufolge musste ich also eine neue Solution erstellen und alle vorhandenen Dateien manuell in die jeweiligen Projekttypen kopieren. Aus oben genannten Gründen wurde für’s Erste völlig auf .NET Core verzichtet, in der Hoffnung, nach der Portierung nach ASP.NET Core auch diese letzte Hürde nehmen zu können. Die Portierung der Klassenbibliotheken verlief ohne größere Probleme: Es war allerdings gelegentlich erforderlich, eine höhere Version der bisher verwendeten Komponenten des .NET Frameworks zu verwenden.

Probleme
ASP.NET Core 1.0 hat seinen eigenen Dependency Injection Container mit derzeit minimaler Funktionalität. Unsere API verwendete bislang Unity für DI; dieser lässt sich zurzeit aber nicht ohne Weiteres einbinden, denn eine offizielle Unterstützung gibt es noch nicht, wenngleich im Internet diverse Personen bereits Einbindungsversuche unternommen haben [2] [3]. Diese sind allerdings mittlerweile veraltet und ein Umstieg auf den mitgelieferten DI-Container war deshalb erforderlich.

Hier konnte ich allerdings bisher keine Möglichkeit finden, die bereits registrierten Interfaces manuell aufzulösen. Anscheinend kann man mit diesem bis jetzt nur Services registrieren, die anschließend bei Bedarf vom ASP.NET Core 1.0 aufgelöst werden.

In einem unserer Projekte verwenden wir auch zwei Bibliotheken für die Kommunikation mit Microsoft Dynamics CRM („Microsoft.Xrm.Client“ und „Microsoft.Xrm.Sdk“). Nach der Übernahme dieser DLLs aus der alten Solution konnten deren Versionen nicht richtig erkannt werden, weswegen neuere Versionen zunächst per NuGet heruntergeladen wurden.

Als schwierigstes Problem hat sich die Portierung der Authentifizierung erwiesen. Unsere API verwendet nämlich ein JWT-Token für die Authentifizierung der Nutzer. Für dessen Verwendung unter ASP.NET Core gibt es eine Unmenge von Beispielen [4] [5], allerdings mittlerweile gänzlich veraltet und teilweise nicht einmal mehr kompilierbar. Am Ende war es mir gelungen herauszufinden, wie man JwtBearerMiddleware im neuen ASP.NET registriert, woraufhin ich allerdings auf neue Probleme gestoßen bin. Die InMemorySymmetricSecurityKey-Klasse, die in unserem Projekt für die Einstellung der TokenValidationParameters verwendet wird, war in der neuesten Version des System.IdentityModel.Tokens-NuGet-Pakets nicht vorhanden.

Im Laufe der Portierung waren bereits einige Kompromisse gemacht worden und bei diesem Problem hat sich Scott Hanselmans Aussage über ASP.NET Core 1.0 bestätigt: ASP.NET 4.6 ist die ausgereiftere Plattform und dies sollte bei der Wahl des zu verwendenden ASP.NET-Frameworks bedacht werden [1]. Mangels Dokumentation und aufgrund veralteter Code-Beispiele wurde letzten Endes die Portierung gestoppt. Denn selbst wenn sie mit großer Mühe erfolgreich gewesen wäre, hätte das Endprodukt aufgrund der schnellen Veränderung von ASP.NET Core 1.0 womöglich bald wieder einer Überarbeitung bedurft.

Fazit
Als modular und betriebssystemübergreifende Technologie ist Microsoft mit ASP.NET Core 1.0 auf dem richtigen Weg. Die Technologie ist derzeit allerdings noch im Entstehen, dementsprechend dürftig sieht es auch in Sachen Dokumentation und Codebeispielen aus. Für eine Portierung unserer bestehenden Web API nach ASP.NET Core ist es deshalb noch etwas zu früh. Wenn ich die Entscheidung über die Wahl des zu verwendenden ASP.NET-Frameworks für die Entwicklung einer neuen ASP.NET Website treffen könnte, so würde ich wohl bis auf Weiteres den sicheren, bereits erprobten Weg gehen: ASP.NET 4.6.

Referenzen
1. http://www.hanselman.com/blog/ASPNET5IsDeadIntroducingASPNETCore10AndNETCore10.aspx

2. http://dzimchuk.net/post/bring-your-own-di-container-to-aspnet-5-unity

3. http://www.fueltravel.com/blog/unity-dependency-injection-in-asp-net-mvc-vnext/

4. http://stackoverflow.com/questions/30553991/asp-net-5-jwt-bearer-token-flow

5. http://stackoverflow.com/questions/32886387/jwt-authentication-in-asp-net-5-using-oauthbearerauthentication