ASP.NET MVC 3 макет данных ViewBag во всех дочерних представлениях

Нам нужны динамические данные, переданные нашему файлу макета, независимо от того, что представляет собой дочерний вид. Например, мы отображаем некоторые пользовательские данные в заголовке макета.

Как мы можем передать эти данные в представление макета без каждого действия, которое должно быть предоставлено независимо? Следует ли использовать пользовательский контроллер или есть лучшее решение?

Ответ 1

Стратегия, которую я использую, состоит в том, чтобы иметь базовую модель представления, из которой выводятся все мои модели взглядов. Я использую базовый контроллер, хотя вы также можете использовать глобальный фильтр и переопределять OnActionExecuted. Когда я обнаруживаю действие, которое возвращает ViewResult, я отбрасываю модель в модель базового представления и устанавливаю общие свойства модели из базового контроллера.

Выбор между глобальным фильтром и базовым контроллером зависит от множества факторов. Если это действительно относится ко всем действиям (которые возвращают результаты просмотра), и вам не нужна инъекция, чтобы получить доступ к некоторым ресурсам, я бы, вероятно, пошел с фильтром. Если вам нужны инъекции зависимостей, или у вас есть некоторые контроллеры, в которых будут применяться данные, а другие - там, где это не было бы (скажем, контроллер администратора), я бы пошел по пути базового контроллера. Вам нужно будет помнить о том, чтобы получить от контроллера, если вы идете с ним.

Вы также можете сделать то же самое с ViewBag, если не хотите выводить из общей модели представления. Мне нравится иметь сильно типизированную модель, но YMMV.

Ответ 3

Взгляните на элементы управления входами, которые являются стандартными в проекте Razor - эти частичные виды доступа к пользовательским данным - вероятно, точно так же, как вы хотели бы.

например. типичный LogonPartial.cshtml может содержать:

@if(Request.IsAuthenticated) {
    <text>Welcome <b>@Context.User.Identity.Name</b>!
    [ @Html.ActionLink("Log Off", "LogOff", "Account") ]</text>
}
else {
    @:[ @Html.ActionLink("Log On", "LogOn", "Account") ]
}