{"id":5096,"date":"2017-01-25T19:36:00","date_gmt":"2017-01-25T17:36:00","guid":{"rendered":"https:\/\/u-labs.de\/portal\/?p=5096"},"modified":"2020-07-17T15:20:19","modified_gmt":"2020-07-17T13:20:19","slug":"asp-net-core-ohne-klassisches-net-framework-nutzen","status":"publish","type":"post","link":"https:\/\/u-labs.de\/portal\/asp-net-core-ohne-klassisches-net-framework-nutzen\/","title":{"rendered":"ASP.NET Core ohne klassisches .NET Framework nutzen"},"content":{"rendered":"<p>Mit .NET Core hat Microsoft den wohl bisher gr\u00f6\u00dften Schritt seit der Geschichte des Frameworks gewagt: Das Framework ist nicht nur quelloffen, sondern l\u00e4uft auf allen g\u00e4ngigen Plattformen. Neben Windows also auch Linux und OS X (Mac). Nun l\u00e4sst sich das neue .NET Core aber auch mit dem alten, klassischen .NET 4.6 kombinieren. Dies kann beispielsweise als \u00dcbergang zur Portierung einer \u00e4lteren Anwendung sinnvoll sein. Oder wenn man Bibliotkenen ben\u00f6tigt, die noch nicht mit .NET Core kompatibel sind.<\/p>\n<p>Zumindest langfristig ist dies aber nicht empfehlenswert, da die wichtigsten Neuerungen von .NET Core so nicht genutzt werden k\u00f6nnen:<\/p>\n<ul>\n<li>Plattformunabh\u00e4ngigkeit<\/li>\n<li>Leichtgewichtiger Kern mit modularem Aufbau<\/li>\n<\/ul>\n<p>Hierf\u00fcr muss man f\u00fcr seine Anwendung vollst\u00e4ndig auf Core setzen. Damit wird es beispielsweise m\u00f6glich, eine ASP.NET Core Webanwendung auf einem Linux-Server zu betreiben. Im Folgenden wird gezeigt, worauf geachtet werden muss. Ausgangspunkt ist ein leeres ASP.NET Core Projekt, das mittels Visual Studio Vorlage erstellt und auf die derzeit aktuellste Version (1.1.0) aktualisiert wurde.<\/p>\n<p><strong>Das Ziel:<\/strong> Die Anwendung soll unabh\u00e4ngig von s\u00e4mtlicher Microsoft-Propriet\u00e4ren Software (Windows, IIS, usw) agieren.<\/p>\n<h4><strong>Anpassung des Zielframeworks<\/strong><\/h4>\n<p>Dies ist der wohl wichtigste Punkt. Wie schon erw\u00e4hnt, k\u00f6nnen wir in einer .NET Core Anwendung das Zielframework festlegen. Dies geschieht im Schl\u00fcssel <strong>frameworks<\/strong>\u00a0der\u00a0<strong>project.json<\/strong> Konfigurationsdatei. In einem aktuellen ASP.NET Core 1.1.0 Projekt sieht dieser meist wie folgt aus:<\/p>\n<pre><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n&quot;frameworks&quot;: {\n    &quot;netcoreapp1.1&quot;: {\n      &quot;dependencies&quot;: {\n        &quot;Microsoft.NETCore.App&quot;: {\n          &quot;type&quot;: &quot;platform&quot;,\n          &quot;version&quot;: &quot;1.1.0&quot;\n        }\n      },\n      &quot;imports&quot;: &quot;dnxcore50&quot;\n    }\n  }\n<\/pre>\n<p>Hier wird festgelegt, dass die Anwendung .NET Core 1.1.0 als Zielframework besitzt. Man kann sich diesen Abschnitt analog zur Auswahl des Zielframeworks in den Projekteigenschaften einer klassischen .NET Windows-Anwendung vorstellen. Dort konnte man beispielsweise .NET Framework 3.5 ausw\u00e4hlen, damit die Anwendung auch auf \u00e4lteren Frameworks l\u00e4uft. Die Funktionen der Nachfolger wie .NET 4.5 standen dann allerdings nicht zur Verf\u00fcgung.<\/p>\n<p>Im Prinzip erledigt dieser Konfigurationsabschnitt die gleiche Aufgabe. Einziger Unterschied: Mit .NET Core ist es m\u00f6glich, mehrere Laufzeitumgebungen zu definieren. \u00dcber Pr\u00e4prozessor-Anweisungen kann z.B. Windows-Spezifischer Code nur auf .NET 4.6 ausgef\u00fchrt werden. Dies wird allerdings ausdr\u00fccklich seitens Microsoft nicht empfehlen, da es verschiedene Risiken birgt. Darauf m\u00f6chte ich auch nicht weiter eingehen,\u00a0weil es f\u00fcr unser Ziel nichts zur Sache tut.<\/p>\n<h4><strong>Anpassung des Zielframeworks<\/strong><\/h4>\n<p>Es existieren eine ganze Reihe von Zielframeworks. Im Folgenden m\u00f6chte ich daher nur kurz auf die wichtigsten drei eingeben. Eine vollst\u00e4ndige, von Microsoft gepflegte Liste ist hier zu finden: <a href=\"https:\/\/docs.microsoft.com\/de-de\/nuget\/schema\/target-frameworks\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">Target Frameworks<\/a><\/p>\n<h5><strong>.NET Standard: netstandard1.2, netstandard 1.5<\/strong><\/h5>\n<p>Microsofts Ansatz, ein Basisframework zu schaffen. Dies soll auf allen .NET Implementierungen gleich sein, und so die Fragmentierung verhindern.\u00a0Im Gegensatz zu .NET Core sind hier nicht nur Desktop- und Server-Betriebssysteme gemeint. Sondern auch unterschiedliche Ger\u00e4tetypen wie beispielsweise Smartphones oder Spielekonsolen.<\/p>\n<h5><strong>.NET Core: netcoreapp1.0,<\/strong>\u00a0<strong>netcoreapp1.1<\/strong><\/h5>\n<p>Bezieht sich auf das neue .NET Core, welches sowohl auf Windows, Linux als auch Mac OS l\u00e4uft. Viele Schnittstellen basieren auf dem klassischen .NET, wenngleich nicht alle verf\u00fcgbar sind (z.B. System.Drawing). Auch durch neue Entwicklungsmuster wie Dependency Injection statt statischer Eigenschaften ist klassischer .NET Core nicht ohne Anpassungen kompatibel.<\/p>\n<h5><strong>Klassisches .NET Framework: net45, net451, net46, net461<\/strong><\/h5>\n<p>Referenziert das alte, klassische .NET Framework, wie wir es bis zum Release von .NET Core kannten. Die Versionsnummern entsprechen auch hier denen der Release, allerdings ohne Punkt. Wer .NET 4.6.1 referenzieren m\u00f6chte, gibt also\u00a0<strong>net461<\/strong> an.<\/p>\n<p>Als Konsequenz bedeutet dies: Wir d\u00fcrfen nur .NET Core oder\u00a0.NET Standard referenzieren. Ansonsten ist unsere Anwendung nicht mehr plattformunabh\u00e4ngig. Wer an dieser Stelle mehr \u00fcber den interessanten .NET Standard Ansatz erfahren m\u00f6chte, sollte einen Blick in die\u00a0<a href=\"https:\/\/github.com\/dotnet\/standard\/blob\/master\/docs\/faq.md\" target=\"_blank\" rel=\"noopener noreferrer nofollow\">.NET Standard FAQ<\/a>\u00a0werfen.<\/p>\n<h4><strong>Sollte man den IIS entfernen?<\/strong><\/h4>\n<p>Ein neues ASP.NET Core Projekt wird in den IIS integriert. Allerdings nicht als plattformspezifisches Modul, wie wir es von den alten ASP.NET Stacks kennen. Stattdessen bringt ASP.NET Core mit\u00a0Kestrel einen eingebauten Webserver mit. Gem\u00e4\u00df des modularen Ansatzes ist er sehr rudiment\u00e4r, und bietet nur den Bruchteil eines <em>vollwertigen<\/em> Webservers wie IIS, Apache oder Nginx. Wer weitreichendere Konfiguration ben\u00f6tigt, muss daher einen der genannten Webserver als Reverse Proxy einsetzen.<\/p>\n<p>Hierf\u00fcr kann man nat\u00fcrlich den IIS nehmen. Das macht aber nur Sinn, wenn die Anwendung zwangsl\u00e4ufig auf einem Windows Server laufen muss &#8211; beispielsweise aufgrund von alten Abh\u00e4ngigkeiten, die noch nicht zum plattform\u00fcbergreifenden .NET Core portiert wurden.<\/p>\n<p>In allen anderen F\u00e4llen macht es Sinn, zumindest \u00fcber Linux nachzudenken: Man setzt auf offene Software, die kontrollierbar ist &#8211; wir erinnern uns an den NSA-Skandal. Der Quellcode eines propriet\u00e4ren Betriebssystemes wie Windows ist geheim, sodass sich darin auch unerw\u00fcnschtes befinden kann. Beispielsweise Hintert\u00fcren oder Spionagefunktionen. Linux ist hier wesentlich transparenter und unabh\u00e4ngig Dar\u00fcber hinaus ist Linux sehr anpassungsf\u00e4hig und es werden keine Lizenzgeb\u00fchren f\u00e4llig. Microsoft kann die Preise jederzeit \u00e4ndern. Ist man darauf angewiesen, hat man keine andere Wahl, als diese zu bezahlen. Wer das f\u00fcr ein theoretisches Szenario h\u00e4lt, sollte mal recherchieren, was sich alleine im Preismodell der neuen Windows Server ge\u00e4ndert hat. Sp\u00e4testens wenn die alten Versionen keine Updates mehr erhalten, bleibt keine andere Wahl. Die alten Preise genie\u00dft man nur noch maximal ein paar Jahre. Das Thema m\u00f6chte ich an dieser Stelle aber nicht ausweiten. Zum IIS sei noch gesagt, dass der Betrieb ohne IIS unter Linux deutlich schlanker vonstatten geht. Vor allem in Kombination mit Docker. Dies verbessert die Leistung, w\u00e4hrend Ressourcenverbrauch und Angriffsfl\u00e4che reduziert werden.<\/p>\n<h4><strong>So wird der IIS aus ASP.NET Core 1.x entfernt<br \/><\/strong><\/h4>\n<p>Im Standard-Template wird<code class=\"\" data-line=\"\">.UseIISIntegration()<\/code>in Program.cs ausgef\u00fchrt und so das IIS-Modul geladen:<\/p>\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-cs\" data-line=\"\">public class Program\n{\n    public static void Main(string[] args)\n    {\n        var config = new ConfigurationBuilder()\n            .AddCommandLine(args)\n            .AddEnvironmentVariables(prefix: &quot;ASPNETCORE_&quot;)\n            .Build();\n\n        var host = new WebHostBuilder()\n            .UseConfiguration(config)\n            .UseKestrel()\n            .UseContentRoot(Directory.GetCurrentDirectory())\n            .UseIISIntegration()\n            .UseStartup&lt;Startup&gt;()\n            .Build();\n\n        host.Run();\n    }\n}<\/code><\/pre>\n<p>Hier entfernt man einfach die Zeile <strong>.UseIISIntegration() <\/strong>und hat damit alle IIS-Abh\u00e4ngigkeiten entfernt. Beim Debuggen in Visual Studio ist darauf zu achten, dass auch hier der integrierte Kestrel-Webserver zum Einsatz kommt. Zu erkennen am Anwendungsname neben dem Debug-Button. Steht dort IIS, ist das nicht der Fall. Da genau das die Standardeinstellung ist, debuggt man in diesem Falle mit dem IIS Express. Dieser wird von Visual Studio automatisch im Hintergrund gestartet. Das ist nat\u00fcrlich wenig sinnvoll, da man so mit einem anderen Webserver arbeitet, der sp\u00e4ter produktiv gar nicht zum Einsatz kommt. Dar\u00fcber hinaus startet Kestrel auch schneller als der IIS, da er deutlich schlanker ist.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mit .NET Core hat Microsoft den wohl bisher gr\u00f6\u00dften Schritt seit der Geschichte des Frameworks gewagt: Das Framework ist nicht nur quelloffen, sondern l\u00e4uft auf allen g\u00e4ngigen Plattformen. Neben Windows also auch Linux und OS X (Mac). Nun l\u00e4sst sich das neue .NET Core aber auch mit dem alten, klassischen .NET 4.6 kombinieren. Dies kann &#8230;<\/p>\n","protected":false},"author":5,"featured_media":6874,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[336,343],"class_list":["post-5096","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technik-news","tag-asp-net","tag-iis"],"_links":{"self":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/5096","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/comments?post=5096"}],"version-history":[{"count":28,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/5096\/revisions"}],"predecessor-version":[{"id":6876,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/5096\/revisions\/6876"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media\/6874"}],"wp:attachment":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media?parent=5096"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/categories?post=5096"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/tags?post=5096"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}