To, co widzę, to właściwość układu ciągu. Ale jak mogę jawnie przekazać model do układu?
c#
.net
asp.net-mvc
razor
SiberianGuy
źródło
źródło
Model
jest dostępny w_Layout
. Używam MVC5.Odpowiedzi:
Wygląda na to, że modelowałeś swoje modele widoków trochę źle, jeśli masz ten problem.
Osobiście nigdy nie napisałbym strony układu. Ale jeśli chcesz to zrobić, powinieneś mieć podstawowy model widoku, z którego dziedziczą inne modele widoku, i wpisz układ do podstawowego modelu widoku, a strony do określonego raz.
źródło
Przykład: kontroler:
Przykładowa góra strony układu
Teraz możesz odwołać się do zmiennej „viewModel” na swojej stronie układu z pełnym dostępem do wpisanego obiektu.
Podoba mi się to podejście, ponieważ to kontroler kontroluje układ, podczas gdy poszczególne modele widoku strony pozostają niezależne od układu.
Uwagi dotyczące MVC Core
Wydaje się, że Mvc Core wysadza zawartość ViewData / ViewBag po pierwszym wywołaniu każdej akcji. Oznacza to, że przypisywanie ViewData w konstruktorze nie działa. Jednak to, co działa, to używanie
IActionFilter
i wykonywanie dokładnie tej samej pracy wOnActionExecuting
. ZałóżMyActionFilter
swójMyController
.źródło
to jest dość podstawowa rzecz, wszystko, co musisz zrobić, to utworzyć model widoku podstawowego i upewnić się, że WSZYSTKIE! i mam na myśli WSZYSTKIE! Twoich widoków, które kiedykolwiek będą używać tego układu, otrzymają widoki korzystające z tego modelu podstawowego!
w _Layout.cshtml:
w metodzie Index (na przykład) w kontrolerze domowym:
plik Index.cshtml:
Nie zgadzam się, że przekazanie modelu do _layout jest błędem, niektóre informacje o użytkowniku mogą zostać przekazane, a dane mogą zostać wypełnione w łańcuchu dziedziczenia kontrolerów, więc potrzebna jest tylko jedna implementacja.
oczywiście dla bardziej zaawansowanych celów należy rozważyć utworzenie niestandardowego kontekstu statycznego przy użyciu wstrzykiwania i dołączyć tę przestrzeń nazw modelu do pliku _Layout.cshtml.
ale dla zwykłych użytkowników to wystarczy
źródło
Typowym rozwiązaniem jest utworzenie modelu widoku bazowego, który zawiera właściwości używane w pliku układu, a następnie dziedziczenie z modelu podstawowego do modeli używanych na odpowiednich stronach.
Problem z tym podejściem polega na tym, że teraz zamknąłeś się w problemie, że model może dziedziczyć tylko z jednej innej klasy, a być może Twoje rozwiązanie jest takie, że nie możesz i tak używać dziedziczenia w modelu, który zamierzałeś.
Moje rozwiązanie również zaczyna się od modelu widoku podstawowego:
Następnie używam ogólnej wersji LayoutModel, która dziedziczy po LayoutModel, na przykład:
Dzięki temu rozwiązaniu wyłączyłem konieczność dziedziczenia między modelem układu a modelem.
Więc teraz mogę iść dalej i użyć LayoutModel w Layout.cshtml w następujący sposób:
Na stronie możesz użyć ogólnego modelu LayoutModel w następujący sposób:
Ze swojego kontrolera po prostu zwracasz model typu LayoutModel:
źródło
Dlaczego po prostu nie dodasz nowego widoku częściowego z własnym, określonym kontrolerem, przekazując wymagany model do widoku częściowego i ostatecznie renderuj wspomniany widok częściowy na swoim Layout.cshtml za pomocą RenderPartial lub RenderAction?
Używam tej metody do wyświetlania informacji o zalogowanym użytkowniku, takich jak imię i nazwisko, zdjęcie profilowe itp.
źródło
stare pytanie, ale żeby wspomnieć o rozwiązaniu dla programistów MVC5, możesz użyć tej
Model
samej właściwości co w widoku.Model
Nieruchomość zarówno widok i układ jest assosiated z tego samegoViewDataDictionary
obiektu, więc nie trzeba wykonywać żadnych dodatkowych prac przekazać swój model na stronie układu, a nie trzeba zadeklarować@model MyModelName
w układzie.Zauważ jednak, że gdy używasz
@Model.XXX
w układzie, menu kontekstowe intelliSense nie pojawi się, ponieważModel
tutaj jest obiektem dynamicznym, tak jakViewBag
.źródło
Może z technicznego punktu widzenia nie jest to właściwy sposób radzenia sobie z tym, ale dla mnie najprostszym i najbardziej rozsądnym rozwiązaniem jest utworzenie klasy i utworzenie jej instancji w układzie. Jest to jednorazowy wyjątek od prawidłowego sposobu wykonania tego. Jeśli jest to zrobione częściej niż w układzie, musisz poważnie przemyśleć to, co robisz, i może przeczytać jeszcze kilka samouczków, zanim przejdziesz dalej w swoim projekcie.
wtedy w widoku
w .net core można to nawet pominąć i użyć iniekcji zależności.
To jeden z tych obszarów, które są trochę zacienione. Ale biorąc pod uwagę niezwykle skomplikowane alternatywy, które tutaj widzę, myślę, że jest to więcej niż dobry wyjątek w imię praktyczności. Zwłaszcza jeśli upewnisz się, że jest to proste i upewnij się, że każda ciężka logika (argumentowałbym, że tak naprawdę nie powinno być, ale wymagania się różnią) znajduje się w innej klasie / warstwie, do której należy. Jest to z pewnością lepsze niż zanieczyszczanie WSZYSTKICH kontrolerów lub modeli ze względu na w zasadzie tylko jeden widok.
źródło
Istnieje inny sposób archiwizacji.
Wystarczy zaimplementować klasę BaseController dla wszystkich kontrolerów .
W
BaseController
klasie utwórz metodę, która zwraca klasę Model, jak na przykład.Layout
stronie możesz wywołać tę metodęGetTopMenu()
źródło
Załóżmy, że Twój model jest zbiorem obiektów (lub może pojedynczym obiektem). Dla każdego obiektu w modelu wykonaj następujące czynności.
1) Umieść obiekt, który chcesz wyświetlić w ViewBag. Na przykład:
2) Dodaj instrukcję using na górze _Layout.cshtml, która zawiera definicję klasy dla twoich obiektów. Na przykład:
@using YourApplication.YourClasses;
3) Kiedy odwołujesz się do obiektu yourObject w _Layout, rzutuj go. Możesz zastosować obsadę dzięki temu, co zrobiłeś w (2).
źródło
Użyj IContainsMyModel w swoim układzie.
Rozwiązany. Reguła dotycząca interfejsów.
źródło
Na przykład
Przeczytaj więcej o nowej dyrektywie @model
źródło