Как получить значение макета по умолчанию из _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, если вызывается напрямую.

Другие вопросы по тегам