{"id":3521,"date":"2016-04-28T19:25:04","date_gmt":"2016-04-28T18:25:04","guid":{"rendered":"https:\/\/u-labs.de\/portal\/?p=3521"},"modified":"2016-04-28T19:47:11","modified_gmt":"2016-04-28T18:47:11","slug":"asp-net-mvc-razor-ansichten-vorkompilieren-fuer-mehr-performance-und-flexibilitaet","status":"publish","type":"post","link":"https:\/\/u-labs.de\/portal\/asp-net-mvc-razor-ansichten-vorkompilieren-fuer-mehr-performance-und-flexibilitaet\/","title":{"rendered":"ASP.NET MVC: Razor-Ansichten vorkompilieren f\u00fcr mehr Performance und Flexibilit\u00e4t"},"content":{"rendered":"<p>Im Gegensatz zum .NET Code werden Razor-Ansichten in ASP.NET zur Laufzeit compiliert. Dies ist recht verbreitet und wird bei anderen serverseitigen Technologien im Web-Bereich wie etwa PHP eben so gehandhabt.\u00a0Bei PHP betrifft dies sogar \u00a0auf den gesamten Code zu, der bei\u00a0<strong>jedem<\/strong> Seitenaufruf vom Interneter aufs neue verarbeitet wird.\u00a0Auf den logischen Programmcode trifft dies bei ASP.NET zwar nicht zu (Stichwort <b>Common Intermediate Language<\/b>, kurz\u00a0<b>CIL<\/b>), wohl aber auf die Razor-Ansichten. Der RazorGenerator erm\u00f6glicht es, die Ansichten bereits beim Erstellen der .NET Anwendung zu kompilieren. Dies erh\u00f6ht die Performance der Webanwendung und reduziert die Serverlast.<\/p>\n<h3><strong>RazorGenerator installieren<\/strong><\/h3>\n<p>Zun\u00e4chst installieren wir das NuGet-Paket <strong>RazorGenerator.Mvc<\/strong> &#8211; wahlweise \u00fcber den grafischen Paketmanager oder mit dem Install-Package Befehl \u00fcber die Konsole:<\/p>\n<pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\r\nInstall-Package RazorGenerator.Mvc\r\n<\/pre>\n<p>Damit Visual Studio den Razor Generator erkennt und die Ansichten automatisch beim Debuggen oder Erstellen\u00a0ebenfalls compiliert, ben\u00f6tigen wir noch die dazugeh\u00f6rige gleichnamige Visual Studio Erweiterung. Um diese zu installieren, navigieren wir \u00fcber das Men\u00fc\u00a0<strong>Extras &gt; Erweiterungen und Updates<\/strong> in den Erweiterungsmanager. \u00dcber die Suche kann der Razor Generator installiert werden:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/u-img.net\/img\/7973Gl.png\" alt=\"\" \/><\/p>\n<p>Anschlie\u00dfend muss Visual Studio neu gestartet werden.\u00a0Leider ist dieser Schritt nicht dokumentiert. Fehlt die Erweiterung, funktioniert der Generator schlicht und einfach nicht. Fehlermeldungen werden keine angezeigt, au\u00dfer man versucht den Vorgang durch Rechtsklick auf die Ansicht &gt;\u00a0<strong>Benutzerdefiniertes Tool<\/strong><strong> ausf\u00fchren<\/strong> manuell zu starten.<\/p>\n<p>Damit eine Razor-Ansicht vorkompiliert wird, muss der RazorGenerator als benutzerdefiniertes Tool in den Eigenschaften definiert werden. Dazu mit der rechten Maustaste auf die View klicken und\u00a0<strong>Eigenschaften<\/strong> ausw\u00e4hlen. Unter\u00a0<strong>Benutzerdefiniertes Tool<\/strong> wird\u00a0<strong>RazorGenerator<\/strong> eingetragen:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/u-img.net\/img\/2631Bo.png\" alt=\"\" \/><\/p>\n<p>Zum testen einfach das Projekt neu erstellen &#8211; Oder alternativ wie oben bereits erw\u00e4hnt das Tool manuell mit einem Rechtsklick auf die View und\u00a0<strong>Benutzerdefiniertes Tool ausf\u00fchren<\/strong>\u00a0starten. In beiden F\u00e4llen sollte anschlie\u00dfend eine der View untergeordnete Datei entstanden sein, die mit\u00a0<strong>.generated.cs<\/strong> endet:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/u-img.net\/img\/2631Bo.png\" alt=\"\" \/><\/p>\n<p>Dies ist die kompilierte View, welche automatisch beim kompilieren des Projektes erzeugt wird. ASP.NET verwendet sie zur Laufzeit, wodurch das wiederkehrende Kompilieren der Razor-Ansicht verhindert wird. Daher sollte man\u00a0<strong>keine<\/strong> \u00c4nderungen an der .generated.cs Datei vornehmen! Diese werden beim n\u00e4chsten Erstellen des Projektes \u00fcberschrieben. Als logische Konsequenz haben \u00c4nderungen an den Originalen Razor-Ansichten (.cshtml Dateien) zur Laufzeit keine Auswirkungen mehr. Dies sollte aber kein Problem darstellen, da in diesem Falle ohnehin das Projekt neu deployt werden sollte.<\/p>\n<p>[box type=&#8220;info&#8220; align=&#8220;aligncenter&#8220; ]Auch wenn sowohl das RazorGenerator NuGet-Paket als auch die Visual Studio Erweiterung installiert sind, werden Razor-Ansichten nicht automatisch vorkompiliert. Dazu ist es wie oben beschrieben n\u00f6tig, das benutzerdefinierte Tool zu setzen. Ob dies funktioniert erkennt man daran, dass die jeweilige Razor-Ansicht eine untergeordnete .generated.cs Datei besitzt. [\/box]<\/p>\n<h3><strong>Weitere Einsatzm\u00f6glichkeit: Teilen von Ansichten<\/strong><\/h3>\n<p>Ein Problem der Razor-Ansichten besteht darin, dass sie sich nicht einfach \u00fcber mehrere Projekte in einer Projektmappe teilen lassen. Beispielsweise wenn man ein zentrales Layout f\u00fcr mehrere Projekte verwenden m\u00f6chte. Hier bieten sich meist nur eher weniger sch\u00f6ne\u00a0Workarounds an\u00a0&#8211; Beispielsweise einen Pre-Build Schritt, der die Ansichten in die gew\u00fcnschten Projekte kopiert. Da vorkompilierte Razor-Ansichten de Facto nur aus einer C#-Klasse bestehen, kann man diese wesentlich einfacher zwischen verschiedenen Projekten teilen.<\/p>\n<p>Wer vor diesem Einsatzszenario steht, sollte sich jedoch fragen, ob mehrere Projekte wirklich notwendig sind. Bereiche (Areas) stellen beispielsweise eine attraktive Alternative dar, die performanter und flexibler ist. Je nach Funktionsumfang kann der Einsatz verschiedener Projekte die miteinander vernetzt sind, auch an anderen Stellen Probleme bereiten.<\/p>\n<h3><strong>Deployment ohne Visual Studio<\/strong><\/h3>\n<p>Die hier vorgestellten Pakete und Erweiterungen integrieren sich in den Buildprozess von Visual Studio. F\u00fcr lokale Tests und kleinere Anwendungen die manuell deployt werden, mag dies kein Problem darstellen. M\u00f6chte man jedoch die Projektmappe selbst mit MsBuild\/MsDeploy Erstellen und deployen, wird dies nicht reibungslos funktionieren. Dies w\u00e4re beispielsweise n\u00fctzlich, wenn man den Deployment-Prozess mittels kontinuierlicher Integration\u00a0automatisieren m\u00f6chte. In diesem Fall muss zus\u00e4tzlich das NuGet-Paket\u00a0<strong>RazorGenerator.MsBuild<\/strong> installiert werden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Gegensatz zum .NET Code werden Razor-Ansichten in ASP.NET zur Laufzeit compiliert. Dies ist recht verbreitet und wird bei anderen serverseitigen Technologien im Web-Bereich wie etwa PHP eben so gehandhabt.\u00a0Bei PHP betrifft dies sogar \u00a0auf den gesamten Code zu, der bei\u00a0jedem Seitenaufruf vom Interneter aufs neue verarbeitet wird.\u00a0Auf den logischen Programmcode trifft dies bei ASP.NET &#8230;<\/p>\n","protected":false},"author":5,"featured_media":3527,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[61],"tags":[336,413,417,418],"class_list":["post-3521","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-softwareentwicklung","tag-asp-net","tag-asp-net-mvc","tag-razor","tag-view"],"_links":{"self":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/3521","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=3521"}],"version-history":[{"count":10,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/3521\/revisions"}],"predecessor-version":[{"id":3950,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/posts\/3521\/revisions\/3950"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media\/3527"}],"wp:attachment":[{"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/media?parent=3521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/categories?post=3521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/u-labs.de\/portal\/wp-json\/wp\/v2\/tags?post=3521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}