Как указать разные макеты в файле ViewStart для бритвы ASP.NET MVC 3?

313

Я хотел бы иметь 2 отдельных макета в моем приложении. Допустим, один предназначен для публичного раздела сайта, а другой - для членов.

Для простоты, скажем, вся логика для каждого из этих сайтов аккуратно обернута в 2 разных контроллера.

  • PublicController
  • StaffController

И что каждый из них имеет соответствующий макет для всех видов под каждым.

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

Как использовать файл _ViewStart.cshtml, чтобы указать, что все View / Action в «Public» используют PublicLayout, а все в «Staff» - StaffLayout?

Спасибо!

Джастин
источник
4
На всякий случай: если вы хотите удалить макет для данного Razorвида, просто установитеLayout = null;
Leniel Maccaferri
3
Как комментарий к вашему примеру, у вас, вероятно, не должно быть контроллеров с именами Public и Staff. Контроллеры чаще всего реализуются в качестве точки входа в CRUD-подобное действие для определенных ключевых бизнес-объектов, таких как EventController, UserController или тому подобное. Если ваше приложение достаточно велико, ответственность государственного / штатного контролера будет слишком большой. Рассмотрим области вместо. msdn.microsoft.com/en-us/library/ee671793%28VS.100%29.aspx Возможно, вы знаете об этом, но кто-то другой, читающий это, может ошибиться, так что просто для записи.
Алекс

Ответы:

558

Вы можете поместить _ViewStart.cshtmlв /Views/Publicпапку файл, который переопределит файл по умолчанию в /Viewsпапке и указать желаемую разметку:

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

По аналогии вы можете поместить другой _ViewStart.cshtmlфайл в /Views/Staffпапку с помощью:

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

Вы также можете указать, какой макет следует использовать при возврате представления внутри действия контроллера, но это для каждого действия:

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

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


ОБНОВИТЬ:

В соответствии с запросом в разделе комментариев приведен пример фильтра действий, который выбирает главную страницу:

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;
        }
    }
}

а затем украсьте контроллер или действие с помощью этого пользовательского атрибута, определяющего макет, который вы хотите:

[LayoutInjecter("_PublicLayout")]
public ActionResult Index()
{
    return View();
}
Дарин димитров
источник
1
@DarinDimitrov Где я буду создавать LayoutInjecterAttribute. ? Есть ли конкретное место?
кбвишну
2
@VeeKeyBee, вы можете поместить его в ActionFiltersподпапку.
Дарин Димитров
Одна потенциальная проблема с LayoutInjecterAttribute: она вызывается передOnException методом контроллера . Таким образом, если контроллер предоставляет результат просмотра во время обработки исключений, макет не будет установлен.
Джефф Шарп
Как новичок в MVC, я бы хотел поблагодарить меня за то, что научил меня этому ответу. Однако я не понимаю, что происходит внутри OnActionExecuted. Можете ли вы обновить ответ для меня.
Имад
29

Еще один метод - определить макет внутри представления:

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

Больше способов сделать можно найти здесь , надеюсь, это кому-нибудь поможет.

shaijut
источник
1
Это не будет работать - без отдельного _ViewStart.cshtml ваше представление будет по-прежнему отображаться внутри метода @RenderBody () в другом макете.
Tillman32
Это! Почему все выдвигают эти чрезвычайно сложные процессы, когда все, что вам нужно сделать, это!
Джордж Харнуэлл
15

Этот метод - самый простой способ для начинающих управлять рендерингом макетов в приложении ASP.NET MVC. Мы можем идентифицировать контроллер и визуализировать макеты как контроллер par, для этого мы можем записать наш код в файл _ViewStart в корневом каталоге папки Views. Ниже приведен пример, показывающий, как это можно сделать.

@{
    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;
}

Прочитайте полную статью здесь "Как сделать разные макеты в ASP.NET MVC"

Анил Шарма
источник