Где и как связан файл макета _ViewStart.cshtml?

Здесь About.cshtml из шаблона MVC по умолчанию:

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

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

Я бы ожидал, что ссылка на файл _ViewStart будет найдена в About.cshtml, но это явно не так.

Я просмотрел global.asax и web.config, но не могу узнать, как файл About.cshtml "связан" с макетом из файла _ViewStart.

Все работает так, как ожидалось, я просто хотел бы узнать, что происходит под капотом...

Ответ 1

Из Блог ScottGu:

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

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

Поскольку этот код выполняется в начале каждого представления, мы больше не необходимо явно установить макет в любом из наших отдельных файлов вида (за исключением случаев, когда мы хотели переопределить значение по умолчанию выше).

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

Это позволяет использовать гибкость пользовательского интерфейса. Это также позволяет вам больше легко написать логику просмотра один раз и не повторять ее в нескольких мест.

Также см. this.

Ответ 2

В более общем смысле эта способность структуры MVC "знать" о _Viewstart.cshtml называется "Кодирование по соглашению" .

Конформационная конфигурация (также известная как кодирование по соглашению) парадигма разработки программного обеспечения, которая стремится уменьшить количество решения, которые разработчики должны делать, приобретая простоту, но не обязательно теряя гибкость. Фраза по существу означает разработчику необходимо указывать нетрадиционные аспекты выражение. Например, если есть класс Sale в модели, соответствующая таблица в базе данных называется "продажа" по умолчанию. Это только если он отклоняется от этого соглашения, например, table "products_sold", что нужно написать код, касающийся этих имена.

Википедия

Там нет волшебства. Его просто записано в основную кодовую базу структуры MVC, и поэтому это то, о чем "знает" MVC. Вот почему вы не находите его в файлах .config или в другом месте; это фактически в коде MVC. Однако вы можете переопределить, чтобы изменить или исключить эти соглашения.

Ответ 3

Еще одна мысль.

Если вы хотите иметь свой собственный cshtml файл в качестве общего шаблона, вы можете сделать это таким образом

В вашем _viewstart.cshtml вы можете указать свой общий файл cshtml.

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

Ответ 4

Исходный код является гораздо лучшим местом для поиска, чем документация.

Ссылаясь на код MVC 6 от Github, у нас есть несколько файлов, представляющих интерес

---- update----

Из-за изменений в структуре источника информацию о том, как собираются страницы viewstart, теперь можно найти в RazorViewEngine.cs, который ищет функцию "GetViewStartPages".

----/update----

Чтобы ответить, как они вступают в игру, посмотрите на RazorView, который, как я считаю (из-за IView), связан с конвейером MVC. Этот файл имеет метод RenderAsync, который вызывается из конвейера MVC для визуализации запрошенного представления.

RenderAsync выполняет вызовы RenderPage И ТОГО RenderLayout (ЗАМЕТЬТЕ ЗАКАЗ). Сначала RenderPage выполняет вызовы для работы с файлами viewstart (обратите внимание, что во множественном числе может быть более одного файла _viewstart).

Таким образом, искомая информация может быть получена из функции RenderViewStartAsync в файле RazorView.cs в пространстве имен Microsoft.AspNet.Mvc.Razor.

Ответ 5

Это может добавить некоторую дополнительную информацию к этому вопросу сейчас (2016 ala MVC4, MVC5).

Механизм Razor находит и запускает код в _ViewStart.cshtml перед любым другим кодом, который находится в том же каталоге или подкаталоге, где находится _ViewStart.cshtml.

Любое представление может переопределить свойство Layout или любое из его значений.

Просто подумал, что мог бы добавить немного больше информации, чтобы показать вам, почему это _ViewStart.

Если вы получите ILSpy и изучите код в RazorViewEngine (System.Web.Mvc.dll), вы увидите, что сам код ссылается на это имя.

_ViewStart in  System.Web.Mvc.dll

Вы можете видеть, что RazorViewEngine ищет файл с таким именем:

razorviewengine code

RazorViewEngine.ViewStartFileName = "_ViewStart";

Ответ 6

Если вы хотите иметь общий макет для своих страниц, вам нужно определить общий макет и связать представление с макетом, мы должны установить свойство макета для каждого вида, это нарушает DRY (не повторяйте себя). Для этого .Net Framework предоставляет файл "_ViewStart.cshtml" , расположенный внутри папки просмотра. Мы размещаем информацию о макете в файле "_ViewStart.cshtml" , и каждое представление по умолчанию использует эту информацию о макете. Если вы хотите предоставить какую-то другую информацию о макете, давайте предположим, что на вашем домашнем представлении вы можете создать новый "_ViewStart.cshtml" со ​​ссылкой на этот макет и поместить его в папку "Домашний просмотр".

Ответ 7

Краткий ответ: ViewStarts запускаются первыми, когда визуализируется любое представление. Длинная история ниже:

История создания одного файла представления:

  1. ViewStart объединяется с ViewImports и затем выполняется как один файл. Обратите внимание, что ViewImports всегда объединяется с любым файлом cshtml, включая файл ViewStart. Его цель - абстрагировать операторы @using и другие общие директивы.
  2. Выходные данные ViewStart (такие как Layout и ViewData) становятся доступными для конкретного файла View.
  3. Внутри файла View, если переменная Layout равна/становится пустой, тело представления визуализируется и окончательный результат доставляется пользователю.
  4. Если переменная Layout равна/становится ненулевой, выполнение перемещается в файл макета, который, в свою очередь, объединяется с ViewImports в виде одного файла, а затем в операторе @RenderBody() внутри файла макета выполнение возвращается обратно в файл представления. который снова сливается с ViewImports, а выходные данные объединяются с файлом макета в месте расположения @RenderBody(), и окончательный результат наконец доставляется пользователю.

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

Ответ 8

У меня тоже была app.UseStaticFiles(); же проблема, и позже я заметил, что app.UseStaticFiles(); отсутствовали в трубопроводе.

Работает после добавления в конвейер.