Примусити всі області використовувати однаковий макет


88

У мене така структура проекту:

  • / Views / Shared / _Layout;

  • / Areas / Area1 / Views / ControllerName / Index;

...

  • / Areas / AreaN / Views / ControllerName / Index.

Чи є спосіб змусити всі області використовувати _Layout як базовий макет ?

Чи є спосіб зробити це без додавання файлу _ViewStart (наприклад, через конфігурацію маршрутизації)?

Дивіться також:

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


Відповіді:


155

Вам просто потрібно додати файл з назвою:

_ViewStart.cshtml

Під папкою переглядів кожної області:

/Areas/Area1/Views/_ViewStart.cshtml

І відредагуйте файл, щоб вказати на кореневий макет так:

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

Для того, щоб це працювало, вам не потрібно вказувати значення у властивості макета подання, якщо ви це зробите, ви б замінили глобальний макет

Примітка: Як згадував Тоні, ви можете редагувати властивість макета кожного подання, щоб вказувати на кореневий макет, однак це не рекомендований спосіб зробити це, оскільки ви поєднуєте свої погляди зі своїм макетом, і змінити це буде боляче

Редагувати 1

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

Спробуйте погуглити про спеціальні RazorViewEngineтаRazorView

Ця стаття може стати гарною відправною точкою

http://weblogs.asp.net/imranbaloch/archive/2011/06/27/view-engine-with-dynamic-view-location.aspx

Я не робив чогось подібного, але, сподіваюся, я вказую вам у правильному напрямку


1
Чи є спосіб зробити це без додавання файлу "_ViewStart" (наприклад, через конфігурацію маршрутизації)?
Михайло

2
В межах маршрутизації я не думаю. Це дві різні речі. Маршрутизація відповідає за спробу зіставити URL-адресу поточного запиту з маршрутом, зареєстрованим у RoutesTable, коли збіг знайдено, створюється IMvcRouteHandler, а потім IHttpHandler (MvcHandler) відповідає за обробку дій вашого контролера. Як бачите, це не має нічого спільного з переглядами та макетами. Це тому, що маршрут не обов’язково повертає подання, він може повернути json або xml. Тож маршрутизація не є правильним місцем для реалізації чогось подібного.
Jupaol

Ви також можете додати _ViewStartбезпосередньо в папку Область, щоб застосувати його до всіх областей.
Артур

21

Розширюючи відповідь Jupaol ....

Принаймні у VS2013 файл _ViewStart.cshtml додається за замовчуванням при створенні області, тож він уже там, і ви можете змінити вміст, коли він зазначає, щоб вказувати на корінь _Layout.cshtml. Потім ви можете видалити _Layout.cshtml у цій області, оскільки він більше не використовується (і потенційне джерело плутанини зараз)

Однак, виконуючи будь-яку маршрутизацію, виконану в цьому кореневому каталозі _Layout.cshtml, потрібно буде врахувати області.
За замовчуванням _Layout.cshtml містить ряд помічників ActionLink, які потребують невеликої модифікації:

Додайте параметр RouteValueDictionary до будь-яких викликів ActionLink, встановивши Area = "". Зверніть увагу, що порожній рядок відноситься до кореневого рівня. Це дозволить цим посиланням працювати належним чином при виклику з певної області, але все одно працюватиме при виклику з кореня.

наприклад:

<li>@Html.ActionLink("Home", "Index", "Home", new { Area = "" }, null)</li>

2

Ви вказуєте макет, використовуючи:

@ {Layout = "_Layout"; }

Якщо ви хочете зробити це простішим, змініть все одразу. Можливо, ви можете просто встановити його як змінну виду перегляду та передати на контролері. Щоб зробити це ще простішим, ви можете створити базовий контролер, який успадковують інші контролери, і попросити його присвоїти макет там мірку перегляду.

Не знаю, чому потрібно змінити маршрутизацію, або, можливо, я не розумію. Сподіваюся, це допомагає :)

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