Wo und wie ist die Layoutdatei _ViewStart.cshtml verknüpft?


199

Hier ist die About.cshtml aus der Standard-MVC 3-Vorlage:

@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<p>
     Put content here.
</p>

Ich würde erwarten, dass ein Verweis auf die _ViewStart-Datei in der gefunden wird About.cshtml, aber dies ist eindeutig nicht der Fall .

Ich habe in global.asaxund gesucht web.config, aber ich kann nicht herausfinden, wie die About.cshtmlDatei mit dem Layout aus der _ViewStart-Datei "verknüpft" ist.

Alles funktioniert wie erwartet, ich möchte nur wissen, was unter der Haube los ist ...

Antworten:


237

Aus ScottGus Blog :

Ab der Beta-Version von ASP.NET MVC 3 können Sie jetzt eine Datei mit dem Namen _ViewStart.cshtml (oder _ViewStart.vbhtml für VB) unter dem Ordner \ Views Ihres Projekts hinzufügen:

Die _ViewStart-Datei kann verwendet werden, um allgemeinen Ansichtscode zu definieren, den Sie zu Beginn des Renderns jeder Ansicht ausführen möchten. Beispielsweise könnten wir Code in unsere Datei _ViewStart.cshtml schreiben, um die Layout-Eigenschaft für jede Ansicht programmgesteuert so festzulegen, dass sie standardmäßig die SiteLayout.cshtml-Datei ist:

Da dieser Code zu Beginn jeder Ansicht ausgeführt wird, müssen wir das Layout in keiner unserer einzelnen Ansichtsdateien mehr explizit festlegen (außer wenn wir den obigen Standardwert überschreiben wollten).

Wichtig: Da wir mit _ViewStart.cshtml Code schreiben können, können wir unsere Layoutauswahllogik optional umfangreicher gestalten als nur einen grundlegenden Eigenschaftssatz. Beispiel: Wir können die Layout-Vorlage, die wir verwenden, je nachdem, welcher Gerätetyp auf die Site zugreift, variieren. Für diese Geräte verfügen wir über ein für Telefone oder Tablets optimiertes Layout und für PCs / Laptops über ein Desktop-optimiertes Layout. Wenn wir ein CMS-System oder eine gemeinsame gemeinsame App erstellen, die von mehreren Kunden verwendet wird, können wir je nach Kunde (oder deren Rolle) beim Zugriff auf die Site unterschiedliche Layouts auswählen.

Dies ermöglicht eine große Flexibilität der Benutzeroberfläche. Außerdem können Sie die Ansichtslogik einfacher einmal schreiben und vermeiden, sie an mehreren Stellen zu wiederholen.

Siehe auch dies .


14
Es ist also mehr oder weniger eine "fest codierte" Funktion von MVC3? Ich muss es nicht auf eine andere "Standard" -Seite ändern, sondern bin nur gespannt, wie es eingerichtet wurde. Vielen Dank, dass Sie alles
geklärt

2
Kman- Hardcoded, gemäß Konvention (wählen Sie hier einen anderen 'Griff' :) :) - also ja, genau.
Ich bin

Möglicherweise benötigen Sie es nicht nur in Ihrem Ordner "Ansichten". Wenn Sie eine benutzerdefinierte RazorViewEngine hinzufügen, um Ansichten in anderen Ordnern zu organisieren, müssen Sie die Datei auch im Stammverzeichnis dieser alternativen Ansichtsordner einfügen. Zum Beispiel habe ich alle Inspinia-Vorlagenansichten in einen Ordner verschoben und diese in der Ansichts-Engine ausgeführt ViewLocationFormats = ViewLocationFormats.Union(new string[] { "~/Inspinia/ExampleViews/{1}/{0}.cshtml" }).ToArray();. Infolgedessen musste ich eine Kopie meiner Datei _ViewStart.cshtml zu "~ / Inspinia / ExampleViews" hinzufügen, da sie sonst nicht aufgenommen und kein Layout festgelegt wurde.
Triynko

2
Wenn Ihr Ordner "Ansichten" Unterordner enthält, können Sie _ViewStartin jeden Unterordner einen Ordner einfügen, der mit den Ansichten in diesem Unterordner verknüpft ist?
Toddmo

35

Im Allgemeinen wird diese Fähigkeit des MVC-Frameworks, _Viewstart.cshtml zu "kennen", als "Codierung nach Konvention" bezeichnet.

Konvention über Konfiguration (auch als Codierung durch Konvention bezeichnet) ist ein Software-Design-Paradigma, das darauf abzielt, die Anzahl der Entscheidungen zu verringern, die Entwickler treffen müssen, um Einfachheit zu erlangen, aber nicht unbedingt an Flexibilität zu verlieren. Der Ausdruck bedeutet im Wesentlichen, dass ein Entwickler nur unkonventionelle Aspekte der Anwendung angeben muss. Wenn das Modell beispielsweise eine Klasse Sale enthält, wird die entsprechende Tabelle in der Datenbank standardmäßig als "sales" bezeichnet. Nur wenn man von dieser Konvention abweicht, beispielsweise die Tabelle "products_sold" aufruft, muss man Code bezüglich dieser Namen schreiben.

Wikipedia

Es gibt keine Magie. Es wurde gerade in die Kerncodebasis des MVC-Frameworks geschrieben und ist daher etwas, von dem MVC "weiß". Deshalb finden Sie es nicht in den .config-Dateien oder anderswo; Es ist tatsächlich im MVC-Code. Sie können diese Konventionen jedoch überschreiben, um sie zu ändern oder auf Null zu setzen.


13
Wenn MVC davon weiß, warum weiß Visual Studio es dann nicht und weist mich darauf hin? Wenn das Codieren nach Konvention bedeutet, dass Dinge funktionieren, solange Sie nicht gegen die Konvention
verstoßen, ist das

Die Konvention nicht zu brechen ist eine Art Punkt. Auch AKAIK Ruby on Rails folgt diesem Paradigma.
Umar Farooq Khawaja

+1 Raif. Es macht keinen Sinn, schlecht dokumentierte "Codierung durch Konvention" zu verteidigen. Ich könnte das über jeden meiner Rückwärtscodes sagen. "Was? Du hast nicht erwartet, dass es abstürzt, wenn es 33 wird? Jeder weiß, dass du 33 überspringst." Leider ist die Dokumentationslücke für ASP.NET MVC sehr groß. Die einzigen MS-Dokumente werden automatisch ohne interne Quellenzusammenfassungen generiert.
Shannon

6
Konvention über Konfiguration bedeutet nicht, dass Sie sie nicht ändern können. Es sollte eine Konfiguration verfügbar sein, um den Namen und den Speicherort dieser Datei angeben zu können. Es mag sehr gut sein, aber wer weiß, was es ist. Die Leute verwenden das Mantra "Konvention über Konfiguration", um eine Vielzahl von schlechten Entscheidungen in einer Codebasis abzudecken, und es hat mich irgendwie verärgert, als der Typ, der nachträglich vorbeikommt, um ihr schlecht dokumentiertes Durcheinander aufrechtzuerhalten, das "einfach funktioniert" (aber) Gott bewahre, dass du etwas änderst - du wirst Stunden damit verbringen herauszufinden, wie du alles kaputt gemacht hast.
Robert C. Barth

3
@AidenStrydom Ich bin anderer Meinung. Die akzeptierte Antwort sagt mir tatsächlich, wie man _ViewStart verwendet. Diese Antwort spricht nur von einem Designkonzept. Ich bin hierher gekommen, um Informationen zu _ViewStart zu erhalten, nicht um Informationen darüber zu erhalten, warum Visual Studio mir nichts über _ViewStart erzählt hat.
Millie Smith

23

Nur ein weiterer Gedanke.

Wenn Sie eine eigene cshtmlDatei als allgemeine Vorlage haben möchten , können Sie dies auf diese Weise tun

In Ihrem können _viewstart.cshtmlSie Ihre gemeinsame cshtmlDatei erwähnen .

@{Layout = "~/Views/Shared/_Layout.cshtml";}

14

Der Quellcode ist ein viel besserer Ort, um danach zu suchen als die Dokumentation.

Unter Bezugnahme auf den MVC 6-Code von Github haben wir einige interessante Dateien

----aktualisieren----

Aufgrund von Änderungen in der Quellstruktur finden Sie die Informationen zum Sammeln von Viewstart-Seiten jetzt in RazorViewEngine.cs. Suchen Sie nach der Funktion "GetViewStartPages".

----/aktualisieren----

Um zu beantworten, wie sie ins Spiel kommen, schauen Sie sich RazorView an , das meiner Meinung nach (aufgrund von IView) mit der MVC-Pipeline verbunden ist. Diese Datei verfügt über eine RenderAsync-Methode, die von der MVC-Pipeline aufgerufen wird, um die angeforderte Ansicht zu rendern.

RenderAsync ruft RenderPage und dann RenderLayout auf (HINWEIS AUF DIE BESTELLUNG). Die RenderPage ruft zuerst auf, um Viewstart-Dateien zu verarbeiten (beachten Sie Plural, es kann mehr als eine _viewstart-Datei geben).

Die gesuchten Informationen können daher über die Funktion RenderViewStartAsync in der Datei RazorView.cs unter dem Namespace Microsoft.AspNet.Mvc.Razor abgerufen werden .


7

Dies kann dieser Frage jetzt einige zusätzliche Informationen hinzufügen (2016 ala MVC4, MVC5).

Die Razor-Engine findet und führt den Code in _ViewStart.cshtml vor jedem anderen Code aus, der sich in demselben Verzeichnis oder Unterverzeichnis befindet, in dem sich die _ViewStart.cshtml befindet.

Jede Ansicht kann die Layout- Eigenschaft oder einen ihrer Werte überschreiben .

Ich dachte nur, ich könnte ein bisschen mehr Informationen hinzufügen, um Ihnen zu zeigen, warum es _ViewStart ist.

Wenn Sie ILSpy erhalten und den Code in der RazorViewEngine (System.Web.Mvc.dll) untersuchen, werden Sie feststellen, dass der Code selbst auf diesen Namen verweist.

_ViewStart in System.Web.Mvc.dll

Sie können sehen, dass die RazorViewEngine nach einer Datei mit diesem Namen sucht:

razorviewengine code

RazorViewEngine.ViewStartFileName = "_ViewStart";

3
das ist, wonach ich gesucht habe, ich hasse es, "nicht zu wissen", was in meinem Projekt vor sich geht, weil ich auch meine eigenen Vorlagen für VS mache und diese Datei, die gerade aus der Luft kam, sehr unhandlich zu verstehen war
Sebastian 506563

1

Wenn Sie ein gemeinsames Layout für Ihre Seiten haben möchten, müssen Sie das gemeinsame Layout definieren und eine Ansicht mit dem Layout verknüpfen. Wir müssen die Layout-Eigenschaften für jede einzelne Ansicht festlegen. Dies verstößt gegen das DRY-Prinzip (Don't Repeat Yourself). Zu diesem Zweck hat .Net Framework die Datei "_ViewStart.cshtml" bereitgestellt, die sich im Ansichtsordner befindet. Wir platzieren Layoutinformationen in der Datei "_ViewStart.cshtml" und jede Ansicht verwendet standardmäßig diese Layoutinformationen. Wenn Sie andere Layoutinformationen angeben möchten, nehmen wir an, Sie können eine neue "_ViewStart.cshtml" mit Bezug auf dieses Layout erstellen und im Ordner "Home View" ablegen.


1

Die kurze Antwort lautet : ViewStarts zuerst gestartet, wenn eine Ansicht gerendert wird. Die lange Geschichte ist unten:

Die Geschichte der Erstellung einer einzelnen Ansichtsdatei:

  1. Der ViewStart wird mit ViewImports zusammengeführt und dann als einzelne Datei ausgeführt. Beachten Sie, dass ViewImports immer mit einer beliebigen cshtml-Datei einschließlich der ViewStart-Datei zusammengeführt wird. Ihr Zweck ist es, @ using-Anweisungen und andere allgemeine Anweisungen zu abstrahieren.
  2. Die Ausgabe von ViewStart (z. B. Layout und ViewData) wird für die jeweilige View-Datei verfügbar.
  3. Wenn in der Ansichtsdatei die Layoutvariable null ist / wird, wird der Hauptteil der Ansicht gerendert und die endgültige Ausgabe an den Benutzer übergeben.
  4. Wenn die Layoutvariable null ist / wird, wird die Ausführung in die Layoutdatei verschoben, die wiederum mit ViewImports als einzelne Datei zusammengeführt wird, und dann bei der Anweisung @RenderBody () in der Layoutdatei wird die Ausführung zurück in die Ansichtsdatei verschoben Dies wird wieder mit ViewImports zusammengeführt und die Ausgabe wird mit der Layoutdatei am Speicherort von @RenderBody () zusammengeführt, und die endgültige Ausgabe wird schließlich an den Benutzer übermittelt.

Hoffentlich macht Sie dies darauf aufmerksam, was wirklich in den unbekannten Geheimnissen des Lebenszyklus Ihres Programms vor sich geht.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.