Wymuś używanie tego samego układu przez wszystkie obszary

88

Mam następującą strukturę projektu:

  • / Views / Shared / _Layout;

  • / Areas / Area1 / Views / ControllerName / Index;

...

  • / Areas / AreaN / Views / ControllerName / Index.

Czy istnieje sposób, aby wymusić na wszystkich obszarach używanie _Layout jako układu podstawowego ?

Czy można to zrobić bez dodawania pliku _ViewStart (na przykład poprzez konfigurację routingu)?

Zobacz też:

Jak określić różne układy w pliku ViewStart Razor ASP.NET MVC 3?

Michaił
źródło
Oto jedna dobra odpowiedź, a druga
Rafael Emshoff,

Odpowiedzi:

155

Musisz tylko dodać plik o nazwie:

_ViewStart.cshtml

W każdym folderze widoków obszaru:

/Areas/Area1/Views/_ViewStart.cshtml

I edytuj plik, aby wskazywał na układ główny w następujący sposób:

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

Aby to zadziałało, nie musisz określać wartości we właściwości układu widoku, jeśli to zrobisz, nadpisujesz układ globalny

Uwaga: Jak wspomniano Tony, ty mógł edytować właściwości układu każdy widok do punktu do układu głównego, jednak nie jest to zalecany sposób, aby to zrobić, ponieważ można byłoby sprzężenie swoje poglądy z układu i zmienić byłoby bolesne

Edytuj 1

Jeśli chcesz użyć kodu do ustawienia domyślnego układu widoku, być może powinieneś rozważyć napisanie niestandardowego silnika widoku.

Spróbuj znaleźć w Google informacje o niestandardowych RazorViewEngineiRazorView

Ten artykuł może być dobrym punktem wyjścia

http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.aspx

Nie zrobiłem czegoś takiego, ale mam nadzieję, że wskazuję ci właściwy kierunek

Jupaol
źródło
1
Czy można to zrobić bez dodawania pliku „_ViewStart” (na przykład poprzez konfigurację routingu)?
Michaił
2
W ramach routingu nie sądzę. To są dwie różne rzeczy. Routing jest odpowiedzialny za próbę dopasowania bieżącego adresu URL żądania do trasy zarejestrowanej w RoutesTable, po znalezieniu dopasowania tworzony jest IMvcRouteHandler, a następnie IHttpHandler (MvcHandler) jest odpowiedzialny za przetwarzanie akcji kontrolera. Jak widać, nie ma to nic wspólnego z widokami ani układami. Dzieje się tak, ponieważ trasa nie musi zwracać widoku, może zwrócić json lub xml. Więc routing nie jest właściwym miejscem do implementacji czegoś takiego.
Jupaol,
Możesz również dodać _ViewStartbezpośrednio w folderze Obszar, aby zastosować go do wszystkich obszarów.
Artur
21

Poszerzenie odpowiedzi Jupaol ....

Przynajmniej w VS2013 plik _ViewStart.cshtml jest dodawany domyślnie podczas tworzenia obszaru, więc już tam jest i możesz zmienić zawartość, jak zauważa, aby wskazywać na katalog główny _Layout.cshtml. Następnie możesz usunąć _Layout.cshtml w tym obszarze, ponieważ nie jest już używany (i jest teraz potencjalnym źródłem zamieszania)

Jednak w ten sposób wszelkie trasy wykonywane w tym katalogu głównym _Layout.cshtml będą musiały uwzględniać obszary.
Domyślny _Layout.cshtml ma kilka pomocników ActionLink, które wymagają niewielkiej modyfikacji:

Dodaj parametr RouteValueDictionary do wszystkich wywołań ActionLink, ustawiając Area = „”. Zauważ, że pusty ciąg odnosi się do poziomu głównego. Pozwoli to tym linkom działać poprawnie, gdy zostaną wywołane z obszaru, nadal będą działać, gdy zostaną wywołane z katalogu głównego.

na przykład:

<li>@Html.ActionLink("Home", "Index", "Home", new { Area = "" }, null)</li>
Rob Campbell
źródło
2

Określasz układ za pomocą:

@ {Layout = "_Layout"; }

Jeśli chcesz to ułatwić, zmień wszystko naraz. Być może mógłbyś po prostu ustawić go jako zmienną worka widoku i przekazać go do kontrolera. Aby było to jeszcze łatwiejsze, możesz utworzyć podstawowy kontroler, z którego dziedziczą inne kontrolery i przypisać układ do worka widoku.

Nie wiem, dlaczego routing miałby się zmienić, a może nie rozumiem. Mam nadzieję że to pomoże :)

Tony
źródło