Де і як пов’язаний файл макета _ViewStart.cshtml?


199

Ось About.cshtml з шаблону MVC 3 за замовчуванням:

@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<p>
     Put content here.
</p>

Я б очікував, що посилання на файл _ViewStart знайдеться у файлі About.cshtml, але очевидно, що це не так.

Я подивився в global.asaxі web.config, але я не можу дізнатися, як About.cshtmlфайл «пов'язаний» з макетом з файлу _ViewStart.

Все працює як очікувалося, я просто хотів би знати, що відбувається під капотом ...

Відповіді:


237

З блогу ScottGu :

Починаючи з випуску бета-версії ASP.NET MVC 3, тепер ви можете додати файл під назвою _ViewStart.cshtml (або _ViewStart.vbhtml для VB) під папкою \ Views вашого проекту:

Файл _ViewStart можна використовувати для визначення загального коду перегляду, який ви хочете виконати на початку кожного відображення перегляду. Наприклад, ми могли написати код у нашому файлі _ViewStart.cshtml, щоб програмно встановити властивість Layout для кожного перегляду як файл SiteLayout.cshtml за замовчуванням:

Оскільки цей код виконується на початку кожного перегляду, нам більше не потрібно чітко встановлювати макет у будь-якому з наших окремих файлів перегляду (за винятком випадків, коли ми хотіли б замінити значення за замовчуванням вище).

Важливо: Оскільки _ViewStart.cshtml дозволяє нам писати код, ми можемо додатково зробити нашу логіку вибору макета багатшою, ніж просто основний набір властивостей. Наприклад: ми можемо змінювати шаблон макета, який ми використовуємо, залежно від типу пристрою, який отримує доступ до сайту, і мати оптимізований для цих пристроїв макет телефону або планшета та макет, оптимізований для настільних ПК для ПК / ноутбуків. Або якщо ми будували систему CMS або загальний спільний додаток, який використовується для кількох клієнтів, ми могли б вибрати різні макети, які використовувати, залежно від замовника (або його ролі) під час доступу до сайту.

Це дає велику гнучкість інтерфейсу користувача. Це також дозволяє легше написати логіку перегляду один раз і уникати повторення в декількох місцях.

Переконайтесь також у цьому .


14
Тож це більш-менш "твердо кодована" особливість MVC3? У мене немає потреби змінювати його на іншу сторінку "за замовчуванням", просто цікаво, як вона була налаштована. Дякую, що ви все розібрали :)
Кман

2
Kman- Hardcoded, за умовою (виберіть іншу "ручку" тут :)) - так, так. рад, що очистив туман
Джим Толлан

Це вам може знадобитися не лише у папці "Перегляди". Якщо ви додаєте спеціальний RazorViewEngine для того, щоб організувати представлення даних в інші папки, ви також повинні включити файл у корінь цих альтернативних папок перегляду. Наприклад, я перемістив усі перегляди шаблонів Inspinia у папку і запустив це в механізмі перегляду ViewLocationFormats = ViewLocationFormats.Union(new string[] { "~/Inspinia/ExampleViews/{1}/{0}.cshtml" }).ToArray();. Як результат, мені довелося додати копію свого файла _ViewStart.cshtml до "~ / Inspinia / ExampleViews", інакше він не був підібраний і не було встановлено макет.
Трайнко

2
Якщо у вашій папці Views є підпапки, чи можете ви помістити _ViewStartу кожну підпапку, яка буде посилатися на представлення даних у цій папці ?
Тоддмо

35

У більш загальному сенсі ця здатність фреймворку MVC "знати" про _Viewstart.cshtml називається "Кодування за умовами ".

Конвенція щодо конфігурації (також відома як кодування за умовами) - це парадигма розробки програмного забезпечення, яка прагне зменшити кількість рішень, які розробники повинні приймати, набуваючи простоти, але не обов'язково втрачаючи гнучкість. Фраза по суті означає, що розробнику потрібно лише вказати нетрадиційні аспекти програми. Наприклад, якщо в моделі є клас Продаж, відповідна таблиця в базі даних за замовчуванням називається «продажі». Лише якщо хтось відхилиться від цієї конвенції, наприклад, називати таблицю "products_sold", потрібно написати код стосовно цих імен.

Вікіпедія

У цьому немає ніякої магії. Його щойно записано в основну кодову базу MVC-фрейму, і тому MVC "знає". Ось чому ви не знайдете його у файлах .config або в інших місцях; це насправді в коді MVC. Однак ви можете змінити або змінити ці умови.


13
Якщо MVC знає про це, то чому Visual Studio не знає і не вказує на це мені? Якщо кодування за умовами означає, що матеріал працює до тих пір, поки у вас не вийде порушити конвенцію, він висмоктує ...
Arne Evertsson

Не порушувати конвенцію - це свого роду суть. AKAIK Ruby on Rails також дотримується цієї парадигми.
Умар Фарук Хавая

+1 Райф. Немає сенсу захищати погано задокументоване "кодування за умовами". Я можу це сказати про будь-який мій зворотній код. "Що? Ви не очікували, що він вийде з ладу, коли він досягне 33? Усі знають, що ви пропустили 33". На жаль, розбіжність у документації для ASP.NET MVC величезна. Єдині документи MS автоматично генеруються без внутрішніх підсумків джерел.
Шеннон

6
Конвенція щодо конфігурації не означає, що ви не можете її змінити. Там ДОЛЖЕН бути наявна конфігурація, щоб можна було вказати ім'я та місцезнаходження цього файлу. Це може бути дуже добре, але хто знає, що це таке. Люди використовують мантру "конвенція про конфігурацію", щоб висвітлити безліч поганих рішень у кодовій базі, і це ніби розчарило мене як хлопця, який приходить за фактом, щоб підтримувати їх погано задокументований безлад, який "просто працює" (але Не дай Бог вам щось змінити - ви витратите години, з'ясовуючи, як ви все зламали).
Роберт Ч. Барт

3
@AidenStrydom Я не згоден. Прийнята відповідь насправді говорить про те, як використовувати _ViewStart. Ця відповідь якраз і говорить про концепцію дизайну. Я прийшов сюди, щоб отримати інформацію про _ViewStart, а не інформацію про те, чому Visual Studio нічого не скаже мені про _ViewStart.
Міллі Сміт

23

Просто інша думка.

Якщо ви хочете мати власний cshtmlфайл як загальний шаблон, ви можете зробити це таким чином

У межах _viewstart.cshtmlви можете згадати ваш загальний cshtmlфайл.

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

14

Вихідний код є набагато кращим місцем для пошуку цього, ніж документація.

Посилання на код MVC 6 з Github, у нас є кілька файлів , що представляють інтерес

---- оновлення ----

Через зміни структури джерела інформацію про те, як збираються сторінки перегляду, тепер можна знайти в RazorViewEngine.cs шукати функцію "GetViewStartPages".

---- / оновлення ----

Щоб відповісти, як вони вступають у гру, подивіться на RazorView , який я вважаю (через IView) прив’язаний до трубопроводу MVC. Цей файл має метод RenderAsync, який отримує виклик з конвеєра MVC для надання потрібного перегляду.

RenderAsync здійснює дзвінки на RenderPage І ТОГО RenderLayout (ПРИМІТКА ЗАМОВЛЕННЯ). Спочатку RenderPage виконує дзвінки для роботи з файлами перегляду (примітка, множина, може бути більше одного файлу _viewstart).

Отже, шукану інформацію можна отримати за допомогою функції RenderViewStartAsync у файлі RazorView.cs під простором імен Microsoft.AspNet.Mvc.Razor.


7

Це може додати деяку додаткову інформацію до цього питання (2016 р. Ala MVC4, MVC5).

Двигун Razor знаходить і запускає код у _ViewStart.cshtml перед будь-яким іншим кодом, який знаходиться в тому самому каталозі або підкаталозі, де знайдено _ViewStart.cshtml .

Будь-який вид може замінити властивість макета або будь-яке його значення.

Просто подумав, я можу додати трохи більше інформації, щоб показати вам, чому це _ViewStart.

Якщо ви отримаєте ILSpy і вивчите код у RazorViewEngine (System.Web.Mvc.dll), ви побачите, що сам код посилається на це ім'я.

_ViewStart в System.Web.Mvc.dll

Ви можете бачити, що RazorViewEngine шукає файл з таким ім'ям:

Код розорвінгу

RazorViewEngine.ViewStartFileName = "_ViewStart";

3
це те, що я шукав, я ненавиджу "не знаю", що відбувається в моєму проекті, тому що я теж роблю власні шаблони для VS, і цей файл, який щойно вийшов з повітря, був дуже неприємний для розуміння
Sebastian 506563

1

Якщо ви хочете мати спільний макет для своїх сторінок, вам потрібно визначити загальний макет і пов’язати вигляд з макетом, ми повинні встановити властивість компонування для кожного перегляду, це порушує принцип DRY (не повторюйте себе). Для цього .Net Framework надав файл "_ViewStart.cshtml", розміщений всередині папки перегляду. Ми розміщуємо інформацію про макет у файлі "_ViewStart.cshtml", і кожен перегляд за замовчуванням використовує цю інформацію про макет. Якщо ви хочете дати деяку іншу інформацію про макет, припустимо, для домашнього перегляду ви можете створити новий "_ViewStart.cshtml" з посиланням на цей макет і помістити його в папку "Перегляд додому".


1

Коротка відповідь : ViewStarts починається спочатку, коли відображається будь-який вид. Довга історія нижче:

Історія створення єдиного файлу перегляду:

  1. ViewStart об'єднується з ViewImports і виконується як єдиний файл. Зауважте, що ViewImports завжди об'єднується з будь-яким файлом cshtml, включаючи файл ViewStart. Її мета - абстрагувати заявки @using та інші загальні директиви.
  2. Вихід ViewStart (наприклад, Layout і ViewData) стає доступним для конкретного файлу View.
  3. Всередині файлу «Перегляд», якщо змінна «Макет» / стає нульовою, тіло подання відображається, а кінцевий висновок доставляється користувачеві.
  4. Якщо змінна Layout / / стає недійсною, виконання переміщується у файл макета, який, у свою чергу, об'єднується з ViewImports як єдиний файл, а потім за допомогою оператора @RenderBody () всередині виконання файлу макета переміщується назад у файл перегляду який знову зливається з ViewImports і вихід об'єднується з файлом макета в місці розташування @RenderBody (), а кінцевий вихід нарешті доставляється користувачеві.

Сподіваємось, що це дає вам знати про те, що насправді відбувається всередині невідомих таємниць життєвого циклу вашої програми.

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