Як вказати різні макети у файлі ViewStart з бритвою ASP.NET MVC 3?


313

Я хотів би, щоб у моїй програмі було 2 окремих макета. Скажімо, один - для публічного розділу веб-сайту, а інший - для учасника.

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

  • PublicController
  • StaffController

І що кожен з них має відповідний макет для всіх представлень під кожним.

  • _PublicLayout.cshtml
  • _StaffLayout.cshtml

Як я можу використовувати файл _ViewStart.cshtml, щоб вказати, що всі перегляди / дії в розділі "Загальнодоступні" використовують PublicLayout, а все в розділі "Персонал" використовує StaffLayout?

Дякую!


4
Про всяк випадок: якщо ви хочете видалити макет для певного Razorвиду, просто встановітьLayout = null;
Леніел Макаферрі

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. ? Чи є якесь конкретне місце?
kbvishnu

2
@VeeKeyBee, ви можете помістити його в ActionFiltersпідпапку.
Дарин Димитров

Одна з потенційних проблем із LayoutInjecterAttribute: Викликається передOnException методом контролера . Отже, якщо контролер надає результат перегляду під час обробки винятків, макет не буде встановлений.
Джефф Шарп

Як новий хлопець в MVC, я хотів би сказати подяку за те, що ви багато навчали мене у цій відповіді. Однак я не розумію, що відбувається всередині OnActionExecuted. Чи можете ви, будь ласка, оновити відповідь для мене.
Імад

29

Ще один спосіб - визначити макет всередині подання:

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

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


1
Це не вийде - без окремого _ViewStart.cshtml ваше представлення все ще відображатиметься всередині методу @RenderBody () в іншому макеті.
Tillman32

Це! Чому всі висувають ці надзвичайно складні процеси, коли все, що вам потрібно зробити, це саме це!
Джордж Харнвелл

15

Цей спосіб є найпростішим способом для початківців контролювати відображення макетів у вашому додатку ASP.NET MVC. Ми можемо ідентифікувати контролер і надати макети як контролер, для цього ми можемо записати наш код у файл _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"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.