Gdzie i jak jest połączony plik układu _ViewStart.cshtml?


199

Oto About.cshtml z domyślnego szablonu MVC 3:

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

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

Spodziewałbym się, że w pliku można znaleźć odwołanie do pliku _ViewStart About.cshtml, ale najwyraźniej tak nie jest.

Szukałem w global.asaxa web.config, ale nie mogę dowiedzieć się, w jaki sposób About.cshtmlplik jest „połączony” z układem z pliku _ViewStart.

Wszystko działa zgodnie z oczekiwaniami, chciałbym tylko wiedzieć, co się dzieje pod maską ...

Odpowiedzi:


237

Z blogu ScottGu :

Począwszy od wersji ASP.NET MVC 3 Beta, możesz teraz dodać plik o nazwie _ViewStart.cshtml (lub _ViewStart.vbhtml dla VB) w folderze \ Views swojego projektu:

Plik _ViewStart może być użyty do zdefiniowania wspólnego kodu widoku, który chcesz wykonać na początku renderowania każdego widoku. Na przykład, moglibyśmy napisać kod w naszym pliku _ViewStart.cshtml, aby programowo ustawić właściwość Układ dla każdego Widoku jako domyślnie plik SiteLayout.cshtml:

Ponieważ ten kod jest wykonywany na początku każdego widoku, nie musimy już jawnie ustawiać układu w żadnym z naszych indywidualnych plików widoku (z wyjątkiem sytuacji, gdy chcieliśmy zastąpić domyślną wartość powyżej).

Ważne: Ponieważ _ViewStart.cshtml pozwala nam pisać kod, możemy opcjonalnie uczynić naszą logikę wyboru układu bogatszą niż tylko podstawowy zestaw właściwości. Na przykład: możemy zmieniać szablon Układu, którego używamy, w zależności od rodzaju urządzenia uzyskującego dostęp do witryny - i mieć zoptymalizowany układ telefonu lub tabletu dla tych urządzeń oraz układ zoptymalizowany pod kątem komputera stacjonarnego dla komputerów stacjonarnych / laptopów. Lub jeśli budowaliśmy system CMS lub wspólną aplikację współdzieloną, która jest używana przez wielu klientów, moglibyśmy wybrać różne układy do użycia w zależności od klienta (lub jego roli) podczas uzyskiwania dostępu do strony.

Umożliwia to dużą elastyczność interfejsu użytkownika. Pozwala także na łatwiejsze jednokrotne zapisanie logiki widoku i unikanie powtarzania jej w wielu miejscach.

Patrz również ten .


14
Czyli jest to mniej więcej „zakodowana” funkcja MVC3? Nie muszę go zmieniać na inną „domyślną” stronę, po prostu ciekawi mnie, jak został skonfigurowany. Dziękujemy za załatwienie wszystkiego :)
Kman

2
Kman- Hardcoded, zgodnie z konwencją (wybierz inny „uchwyt” tutaj :)) - więc tak, dokładnie. cieszę się, że oczyścił mgłę
Jim Tollan

Może nie być potrzebny tylko w folderze „Widoki”. Jeśli dodasz niestandardowy RazorViewEngine w celu uporządkowania widoków w innych folderach, musisz również dołączyć plik do katalogu głównego tych alternatywnych folderów widoków. Na przykład przeniosłem wszystkie widoki szablonów Inspinia do folderu i uruchomiłem to w silniku widoku ViewLocationFormats = ViewLocationFormats.Union(new string[] { "~/Inspinia/ExampleViews/{1}/{0}.cshtml" }).ToArray();. W rezultacie musiałem dodać kopię mojego pliku _ViewStart.cshtml do „~ / Inspinia / ExampleViews”, w przeciwnym razie nie został on pobrany i nie został ustawiony żaden układ.
Triynko,

2
Jeśli twój folder Widoki ma podfoldery, czy możesz umieścić _ViewStartw każdym podfolderze link do widoków w tym podfolderze?
toddmo

35

W bardziej ogólnym znaczeniu ta zdolność frameworka MVC do „wiedzieć” o _Viewstart.cshtml nazywa się „Kodowaniem według konwencji”.

Konwencja o konfiguracji (zwana również konwencją kodowania) jest paradygmatem projektowania oprogramowania, który ma na celu zmniejszenie liczby decyzji, które programiści muszą podejmować, uzyskując prostotę, ale niekoniecznie tracąc elastyczność. Wyrażenie to zasadniczo oznacza, że ​​programista musi jedynie określić niekonwencjonalne aspekty aplikacji. Na przykład, jeśli w modelu jest klasa Sprzedaż, odpowiednia tabela w bazie danych jest domyślnie nazywana „sprzedażą”. Tylko jeśli ktoś odejdzie od tej konwencji, na przykład nazywając tabelę „produkty_przedane”, trzeba napisać kod dotyczący tych nazw.

Wikipedia

Nie ma w tym magii. Właśnie został zapisany w podstawowej bazie kodu frameworka MVC i dlatego jest czymś, o czym MVC „wie”. Dlatego nie znajdziesz go w plikach .config lub gdzie indziej; jest w rzeczywistości w kodzie MVC. Możesz jednak zastąpić te konwencje lub je anulować.


13
Jeśli MVC o tym wie, to dlaczego Visual Studio nie wie o tym i nie zwraca mi na to uwagi? Jeśli kodowanie przez konwencję oznacza, że ​​rzeczy działają tak długo, jak długo zdarzy się, że nie złamiesz konwencji, to trochę do bani ...
Arne Evertsson,

Nie złamanie konwencji jest w pewnym sensie sednem. AKAIK Ruby on Rails również przestrzega tego paradygmatu.
Umar Farooq Khawaja

+1 Raif. Nie ma sensu bronić słabo udokumentowanego „kodowania umownego”. Mógłbym powiedzieć to na temat dowolnego mojego kodu wstecznego. „Co? Nie spodziewałeś się, że nastąpi awaria, gdy osiągnie 33? Wszyscy wiedzą, że pomijasz 33.” Niestety luka w dokumentacji dla ASP.NET MVC jest ogromna. Jedyne dokumenty MS są generowane automatycznie bez wewnętrznych podsumowań źródeł.
shannon

6
Konwencja dotycząca konfiguracji nie oznacza, że ​​nie możesz jej zmienić. POWINNA istnieć konfiguracja umożliwiająca określenie nazwy i lokalizacji tego pliku. Może być, ale kto wie, co to jest. Ludzie używają mantry „konwencja nad konfiguracją”, aby opisać wiele kiepskich decyzji w bazie kodu i trochę mnie to wkurzyło jako facet, który pojawia się po fakcie, aby utrzymać swój źle udokumentowany bałagan, który „po prostu działa” (ale Boże, nie zmieniaj niczego - spędzisz godziny zastanawiając się, jak wszystko zepsułeś).
Robert C. Barth

3
@AidenStrydom Nie zgadzam się. Akceptowana odpowiedź faktycznie mówi mi, jak korzystać z _ViewStart. Ta odpowiedź mówi tylko o koncepcji projektowej. Przybyłem tutaj, aby uzyskać informacje na temat _ViewStart, a nie informacje o tym, dlaczego Visual Studio nie powiedziałby mi nic o _ViewStart.
Millie Smith

23

Kolejna myśl.

Jeśli chcesz mieć własny cshtmlplik jako wspólny szablon, możesz to zrobić w ten sposób

W swoim _viewstart.cshtmlmożna wymienić swój wspólny cshtmlplik.

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

14

Kod źródłowy jest znacznie lepszym miejscem do poszukiwania tego niż dokumentacja.

Odwołując się do kodu MVC 6 z Github, mamy kilka interesujących plików

----aktualizacja----

Ze względu na zmiany struktury źródła informacje o tym, jak gromadzone są strony podglądu, można teraz znaleźć w RazorViewEngine.cs szukać funkcji „GetViewStartPages”.

----/aktualizacja----

Aby odpowiedzieć na pytanie, w jaki sposób wchodzą w grę, spójrz na RazorView , który moim zdaniem (z powodu IView) jest powiązany z potokiem MVC. Ten plik ma metodę RenderAsync, która jest wywoływana z potoku MVC w celu renderowania żądanego widoku.

RenderAsync wykonuje połączenia z RenderPage, a następnie RenderLayout (UWAGA ZAMÓWIENIE). RenderPage najpierw wykonuje wywołania w celu obsługi plików viewstart (uwaga w liczbie mnogiej, może istnieć więcej niż jeden plik _viewstart).

Tak więc informacje, których szukasz, można uzyskać z funkcji RenderViewStartAsync w pliku RazorView.cs w obszarze nazw Microsoft.AspNet.Mvc.Razor.


7

To może teraz dodać dodatkowe informacje do tego pytania (2016 ala MVC4, MVC5).

Silnik Razor znajduje i uruchamia kod w _ViewStart.cshtml przed każdym innym kodem, który znajduje się w tym samym katalogu lub podkatalogu, w którym znajduje się _ViewStart.cshtml .

Każdy widok może zastąpić właściwość Układ lub dowolną jej wartość.

Pomyślałem, że mogę dodać trochę więcej informacji, aby pokazać, dlaczego jest to _ViewStart.

Jeśli otrzymasz ILSpy i sprawdzisz kod w RazorViewEngine (System.Web.Mvc.dll), zobaczysz, że sam kod odwołuje się do tej nazwy.

_ViewStart w System.Web.Mvc.dll

Możesz zobaczyć, że RazorViewEngine szuka pliku o tej nazwie:

kod razorviewengine

RazorViewEngine.ViewStartFileName = "_ViewStart";

3
tego właśnie szukałem, nienawidzę „nie wiem”, co się dzieje w moim projekcie, ponieważ robię również własne szablony dla VS, a ten plik, który właśnie wyszedł z powietrza, był bardzo niewygodny do zrozumienia
Sebastian 506563

1

Jeśli chcesz mieć wspólny układ dla swoich stron, musisz zdefiniować wspólny układ i powiązać widok z układem, musimy ustawić właściwość układu dla każdego widoku, co narusza zasadę DRY (Don't Repeat Yourself). Do tego .NET Framework udostępnia plik „_ViewStart.cshtml”, umieszczony w folderze widoku. Umieszczamy informacje o układzie w pliku „_ViewStart.cshtml” i każdy widok domyślnie korzysta z tych informacji o układzie. Jeśli chcesz podać inne informacje o układzie, załóżmy, że w widoku głównym możesz utworzyć nowy plik „_ViewStart.cshtml” w odniesieniu do tego układu i umieścić go w folderze „Widok główny”.


1

Krótka odpowiedź brzmi : ViewStarts zaczyna się najpierw, gdy renderowany jest dowolny widok. Długa historia jest poniżej:

Historia tworzenia jednego pliku widoku:

  1. ViewStart jest łączony z ViewImports, a następnie wykonywany jako pojedynczy plik. Zauważ, że ViewImports jest zawsze scalany z dowolnym plikiem cshtml, w tym plikiem ViewStart. Jego celem jest wyodrębnienie @używających wypowiedzi i innych wspólnych dyrektyw.
  2. Dane wyjściowe ViewStart (takie jak Layout i ViewData) stają się dostępne dla określonego pliku View.
  3. Wewnątrz pliku widoku, jeśli zmienna układu ma wartość / staje się pusta, treść widoku jest renderowana, a ostateczne wyjście jest dostarczane do użytkownika.
  4. Jeśli zmienna Layout ma wartość / staje się pusta, wykonanie jest przenoszone do pliku układu, który z kolei jest scalany z ViewImports jako pojedynczy plik, a następnie w instrukcji @RenderBody () wewnątrz pliku układu jest przenoszony z powrotem do pliku widoku który ponownie łączy się z ViewImports, a dane wyjściowe są scalane z plikiem układu w lokalizacji @RenderBody (), a końcowe dane wyjściowe są ostatecznie dostarczane do użytkownika.

Mam nadzieję, że dzięki temu zdasz sobie sprawę z tego, co naprawdę dzieje się w nieznanych tajemnicach cyklu życia Twojego programu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.