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

313

Chciałbym mieć 2 osobne układy w mojej aplikacji. Powiedzmy, że jeden jest przeznaczony do części publicznej strony internetowej, a drugi do strony członka.

Dla uproszczenia załóżmy, że cała logika każdego z tych miejsc jest starannie zapakowana w 2 różne kontrolery.

  • PublicController
  • StaffController

I że każdy z nich ma odpowiedni Układ dla całego Widoku pod każdym.

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

Jak użyć pliku _ViewStart.cshtml, aby określić, że wszystkie Widoki / Akcje w „Publicznym” używają PublicLayout, a wszystko w „Staff” korzysta z StaffLayout?

Dzięki!

Justin
źródło
4
Na wszelki wypadek: jeśli chcesz usunąć układ dla danego Razorwidoku, po prostu ustawLayout = null;
Leniel Maccaferri
3
Podobnie jak komentarz do twojego przykładu, prawdopodobnie nie powinieneś mieć kontrolerów o nazwach Public i Staff. Kontrolery są najczęściej implementowane jako punkt wejścia do akcji podobnej do CRUD w niektórych kluczowych jednostkach biznesowych, takich jak EventController, UserController lub tym podobne. Jeśli twoje podanie jest dość duże, odpowiedzialność kontrolera publicznego / personelu byłaby zbyt szeroka. Zamiast tego rozważ obszary. msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspx Być może zdajesz sobie z tego sprawę, ale ktoś inny, kto to czyta, może mieć zły pomysł, więc na wszelki wypadek.
Alex

Odpowiedzi:

558

Możesz umieścić _ViewStart.cshtmlplik w /Views/Publicfolderze, który zastąpi domyślny w /Viewsfolderze i określi pożądany układ:

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

Analogicznie możesz umieścić _ViewStart.cshtmlw /Views/Stafffolderze inny plik z:

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

Możesz również określić, który układ powinien zostać użyty podczas zwracania widoku wewnątrz akcji kontrolera, ale to na akcję:

return View("Index", "~/Views/Shared/_StaffLayout.cshtml", someViewModel);

Jeszcze inną możliwością jest niestandardowy filtr akcji, który zastąpiłby układ. Jak widać wiele możliwości osiągnięcia tego celu. Od Ciebie zależy, który z nich najlepiej pasuje do Twojego scenariusza.


AKTUALIZACJA:

Zgodnie z żądaniem w sekcji komentarzy, oto przykład filtru akcji, który wybrałby stronę wzorcową:

public class LayoutInjecterAttribute : ActionFilterAttribute
{
    private readonly string _masterName;
    public LayoutInjecterAttribute(string masterName)
    {
        _masterName = masterName;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var result = filterContext.Result as ViewResult;
        if (result != null)
        {
            result.MasterName = _masterName;
        }
    }
}

a następnie udekoruj kontroler lub akcję za pomocą tego niestandardowego atrybutu określającego pożądany układ:

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}
Darin Dimitrov
źródło
1
@DarinDimitrov Where I will create LayoutInjecterAttribute. ? Czy jest jakaś konkretna lokalizacja?
kbvishnu
2
@VeeKeyBee, możesz umieścić go w ActionFilterspodfolderze.
Darin Dimitrov
Jeden potencjalny problem z LayoutInjecterAttribute: Jest wywoływany przedOnException metodą kontrolera . Jeśli więc kontroler zapewnia wynik widoku podczas obsługi wyjątków, układ nie zostanie ustawiony.
Jeff Sharp
Jako nowy facet w MVC chciałbym podziękować za nauczenie mnie dużo w tej odpowiedzi. Jednak nie rozumiem, co się dzieje w środku OnActionExecuted. Czy możesz zaktualizować odpowiedź dla mnie.
Imad
29

Jeszcze jedną metodą jest zdefiniowanie układu w widoku:

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

Więcej sposobów zrobienia można znaleźć tutaj , mam nadzieję, że to komuś pomoże.

Shaijut
źródło
1
To nie zadziała - bez osobnego _ViewStart.cshtml widok nadal będzie renderowany w metodzie @RenderBody () w innym układzie.
Tillman32,
To! Dlaczego wszyscy przedstawiają te niezwykle złożone procesy, skoro wszystko, co musisz zrobić, to!
George Harnwell
15

Ta metoda jest dla początkujących najprostszym sposobem kontrolowania renderowania układów w aplikacji ASP.NET MVC. Możemy zidentyfikować kontroler i wyrenderować Layouty jako par kontrolera, w tym celu możemy napisać nasz kod w pliku _ViewStart w katalogu głównym folderu Views. Poniżej znajduje się przykład pokazujący, jak można to zrobić.

@{
    var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
    string cLayout = "";

    if (controller == "Webmaster")
        cLayout = "~/Views/Shared/_WebmasterLayout.cshtml";
    else
        cLayout = "~/Views/Shared/_Layout.cshtml";

    Layout = cLayout;
}

Przeczytaj cały artykuł tutaj „Jak renderować inny układ w ASP.NET MVC”

Anil Sharma
źródło