Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Ранее мы рассмотрели функциональность шаблонов формирования, которые позволяют автоматизировать процесс создания контроллера и представлений. Однако иногда их функциональности бывает недостаточно, и возникает необходимость переопределить их поведение.
Для начала посмотрим, что представляют имеющиеся шаблоны. Все шаблоны для Visual Studio 2013 хранятся в папке C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates. Эта папка содержит следующие подкаталоги:
Все подкаталоги представляют шаблоны, на основе которых генерируется код контроллеров или представлений. В частности, каталог MvcView содержит шаблоны для генерации представлений:
Шаблон представляет собой файл с расширением .t4, который содержит ряд директив, по которым затем генерируется код. Например, наиболее маленький шаблон Empty.cs.t4 имеет следующий код:
<#@ template language="C#" HostSpecific="True" #> <#@ output extension=".cshtml" #> <#@ include file="Imports.include.t4" #> @model <#= ViewDataTypeName #> <# // The following chained if-statement outputs the file header code and markup for a partial view, a view using a layout page, or a regular view. if(IsPartialView) { #> <# } else if(IsLayoutPageSelected) { #> @{ ViewBag.Title = "<#= ViewName#>"; <# if (!String.IsNullOrEmpty(LayoutPageFile)) { #> Layout = "<#= LayoutPageFile#>"; <# } #> } <h2><#= ViewName#></h2> <# } else { #> @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title><#= ViewName #></title> </head> <body> <# PushIndent(" "); } #> <# if(!IsPartialView && !IsLayoutPageSelected) { #> <div> </div> <# } #> <# // The following code closes the tag used in the case of a view using a layout page and the body and html tags in the case of a regular view page #> <# if(!IsPartialView && !IsLayoutPageSelected) { ClearIndent(); #> </body> </html> <# } #>
Все директивы и управляющие блоки шаблонов помещаются между тегами <#
и #>
. Например, директива <#@ output extension=".cshtml" #>
указывает,
что выходной файл после обработки должен иметь расширение .cshtml.
Блоки обычного текста располагаются вне тегов <#
и #>
. Блоки текста не обрабатываются и помещаются в выходной файл как есть.
Мы можем изменить какой-либо шаблон из существующих, однако изменение затронет все последующие случаи использования данного шаблона. И чтобы не менять глобально, мы можем добавить нужные шаблоны в проект в Visual Studio. Шаблоны из проекта в Visual Studio переопределяют поведение глобальных шаблонов из каталога C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates для данного проекта.
Чтобы переопределить шаблон, нам надо создать в проекте папку с именем CodeTemplates. А в нее затем поместить те шаблоны, которые надо переопределить. Например, переопределим шаблон Delete.cs.t4:
Поскольку шаблон Delete.cs.t4 находится в папке MvcView, то в прокте надо создать соответствующую папку в CodeTemplates и затем скопировать туда шаблон. Кроме того, я добавил еще пару файлов, от которых зависит Delete.cs.t4 и которые также находятся в папке C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates\MvcView
Теперь изменим код шаблона Delete.cs.t4 на следующий:
<#@ template language="C#" HostSpecific="True" #> <#@ output extension=".cshtml" #> <#@ include file="Imports.include.t4" #> <h2>Шаблон удаления</h2>
Этот шаблон по сути ничего не делает кроме того, что выводит заголовок.
Первая директива указывает, что будет использоваться язык C#. Вторая строка говорит, что выходной файл будет иметь расширение .cshtml, а третья строка подключает файл.
Теперь, если мы попытаемся создать представление по шаблону Delete, то Visual Studio сгенерирует файл со следующим содержанием:
<h2>Шаблон удаления</h2>
Теперь создадим уже свой более осмысленный шаблон. Для этого добавим в проект в папку CodeTemplates/MvcView какой-нибудь файл или другой шаблон и переименуем его на MyTemplate:
Определим в нем следующий код:
<#@ template language="C#" HostSpecific="True" #> <#@ output extension=".cshtml" #> <#@ include file="Imports.include.t4" #> @model <#= ViewDataTypeName #> <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>MyTemplate</title> </head> <body> <h2><#= ViewName#></h2> <table> <# foreach (PropertyMetadata property in ModelMetadata.Properties) { if (property.Scaffold && !property.IsPrimaryKey && !property.IsForeignKey) { #> <tr> <td> <b> @Html.DisplayNameFor(model => model.<#= GetValueExpression(property) #>) </b> </td> <td> @Html.DisplayFor(model => model.<#= GetValueExpression(property) #>) </td> </tr> <# } } #> </table> </body> </html> <#@ include file="ModelMetadataFunctions.cs.include.t4" #>
Этот шаблон принимает модель из контроллера и выводит все значения ее свойств в виде таблицы. Теперь мы можем использовать этот шаблон при создании представлений: