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

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

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

  • PublicController
  • StaffController

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

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

Как использовать файл _ViewStart.cshtml, чтобы указать, что все представления / действия в разделе Public используют PublicLayout, а все элементы в разделе Staff используют StaffLayout?


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


Ответы (3)


Вы можете поместить файл _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();
}
person Darin Dimitrov    schedule 01.03.2011
comment
@DarinDimitrov Где я буду создавать LayoutInjecterAttribute. ? Есть ли какое-то конкретное место? - person kbvishnu; 18.07.2012
comment
@VeeKeyBee, вы можете поместить его в подпапку ActionFilters. - person Darin Dimitrov; 18.07.2012
comment
Одна потенциальная проблема с LayoutInjecterAttribute: он вызывается перед методом OnException контроллера. Итак, если контроллер предоставляет результат просмотра во время обработки исключений, макет не будет установлен. - person Jeff Sharp; 21.04.2014
comment
Как новичок в MVC, я хотел бы поблагодарить за то, что многому меня научил в этом ответе. Однако я не понимаю, что происходит внутри OnActionExecuted. Не могли бы вы обновить ответ для меня. - person Imad; 24.11.2014

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

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

Другие способы сделать это можно найти здесь, надеюсь, это кому-то поможет.

person Shaiju T    schedule 21.02.2015
comment
Это не сработает - без отдельного _ViewStart.cshtml ваше представление все равно будет отображаться внутри метода @RenderBody () в другом макете. - person Tillman32; 05.12.2016
comment
Этот! Почему все выдвигают эти чрезвычайно сложные процессы, когда все, что вам нужно сделать, это это! - person George Harnwell; 13.02.2018

Этот метод - самый простой способ для новичков управлять отрисовкой макетов в приложении 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;
}
person Anil Sharma    schedule 08.10.2014