Как получить значение макета по умолчанию из _ViewStart.cshtml в MVC/Razor
У меня есть методы расширения для MVC Controller
класс, который должен знать, каков текущий файл макета по умолчанию (то есть значение из _ViewStart.cshtml
).
Код находится в библиотеке, поэтому у меня есть только контроллер для запуска. Приведенный ниже код в основном позволяет любому действию контроллера всегда возвращать PartialPage, но условно назначает макет макета по умолчанию (делая его полным представлением), если он не был в ответ на запрос Ajax (например, чтобы просмотреть всю страницу для отладки).
например
public static void RenderMode(this Controller controller)
{
if (!controller.Request.IsAjaxReuest())
{
controller.ViewBag.Layout = ????????;
}
}
Итак, вопрос в том, как получить значение макета страницы по умолчанию из кода?
1 ответ
Согласно комментарию от Андреаса (спасибо), необходимые настройки скрыты в классе RazorViewEngine и недоступны.
Обновление сентябрь 2015 - новое решение!
Недавно мы нашли лучший способ сделать это без агрессивных изменений в любом коде действия.
шаги:
- Унаследовать все контроллеры от общего
BaseController
учебный класс. - Добавить
OnActionExecuting
переопределить метод кBaseController
, - Вызов
RenderMode()
изнутри этого метода - так это будет происходить для всех запросов, прежде чем будет вызвано действие. - + Изменить
RenderMode()
установитьViewBag.Layout = null
для запросов страниц Ajax. - Внутри _ViewStart.cshtml добавьте код, чтобы установить для макета значение ViewBag.
BaseController.cs - RenderMode ()
public void RenderMode(string layout)
{
if (IsPartialPage)
{
// Wipe any existing layout page
ViewBag.Layout = null;
return;
}
ViewBag.Layout = layout;
}
ViewStart.cshtml
@{
Layout = (string)ViewContext.Controller.ViewBag.Layout;
}
Конечным результатом является то, что вы можете вернуть View()
или PartialView()
как обычно, и представление будет отображаться как полное или частичное представление на основе проверки "ajax", выполненной перед выполнением действия. Это значительно упростило наши веб-сайты, поскольку мы можем использовать больше стандартного кода скаффолдинга как есть.
Предыдущее решение (сейчас устарело)
Поэтому мой обходной путь - передать макет по умолчанию RenderMode
метод расширения:
т.е.
public static void RenderMode(this Controller controller, layout)
{
if (!controller.Request.IsAjaxReuest())
{
controller.ViewBag.Layout = layout;
}
}
и вызов с любого контроллера, подобного этому (или с использованием константы, известной приложению):
public ActionResult SomeAction()
{
var vm = new SomeViewModel();
RenderMode("~/views/shared/_MainLayout.cshtml");
return PartialView(vm);
}
Конечным результатом является частичное представление при вызове из Ajax или полное представление с использованием _mainLayout.cshtml
, если вызывается напрямую.