| Понедельник, 18 февраля, 2013
Метки: Razor, ASP.NET MVC Комментарии: 0
В Razor создавать блоки с кодом можно почти везде, используя @{ }. Код, написанный в такой конструкции ничего не генерирует на веб страницу, но вы можете использовать его для манипуляций с моделью, объявления переменных и т.п. Правда не надо переусердствовать и писать много кода в представлении - это не лучшее место для написания логики.
@{ var message = "Привет, мир!"; } @message @for (var i = 0; i < 10; i++) { <div>@message</div> }
В коде выше объявлена строковая переменная message. Эту переменную можно использовать дальше во всем представлении.
Если не понятно, почему переменная message используется снаружи блока фигурных скобок { } (что было бы неправильно в файле .cs), то нужно отметить, что блоки с кодом в Razor представлениях - это не тоже самое, что блоки с кодом в C#. Вы можете увидеть это, если откроете код сгенерированный шаблоном Razor. Для этого можно намеренно добавить ошибку компиляции в представление, запустить приложение, а затем на странице с информацией об ошибке кликнуть ссылку “Show Complete Compilation Source” (Показать весь скопилированный код). Или можно посмотреть полный код в значении переменной Assembly.GetExecutingAssembly().CodeBase.
Для вышеприведенного примера сгенерированный код выглядит так:
public class TheView : WebViewPage<dynamic> { public override void Execute() { var message = "Hello, World!"; Write(message); for (var i = 0; i < 10; i++) { WriteLiteral("<div>"); Write(message); WriteLiteral("</div>"); } } }
Это упрощенный код, но он хорошо показывает настоящую область видимости переменной message.
Razor обычно хорошо справляется с распознаванием кода C# и HTML. Но есть и случаи, когда он этого не может сделать правильно без некоторых дополнений. Например, когда нужно вывести текст перед выражением, которое выводит свое значение на страницу. Допустим, нужно вывести префикс “СН” в виде текста перед переменной, выводящей номер.
PN@Model.PartNumber
В этом случае Razor воспримет строку как email адрес и на странице так и покажет PN@Model.PartNumber. Для разрешения этой проблемы нужно заключить выражение в круглые скобки.
PN@(Model.PartNumber)
Это выдаст желаемый результат - "PN10400".
Другие проблемы могут возникнуть при размещении текста и кода C# вместе. Razor довольно легко справляется с текстом, если он размещен в HTML разметке.
@foreach(var item in Model) { <div>@item</div> }
Но, он не сможет сделать правильное распознавание, если встретится текст в коде C#.
@foreach(var item in Model) { Элемент: @item }
Здесь Razor пытается интерпретировать слово "Элемент", как какое-то выражение C#, и выдает ошибку компиляции. Простым решением будет воспользоваться символами "@:", чтобы переключится с C# на текст. Либо заключить текст в специальный тег <text></text>
@foreach(var item in Model) { @:Элемент: @item }
Комментарии в Razor начинаются символами "@*" и оканчиваются "*@". Ничего внутри закомментаренной области не будет обработано и не попадет на страницу, даже HTML.
@* <span>Этот текст не будет показан</span> @foreach(var item in Model) { @:Item: @item } *@
Когда вы используете html-хелперы, часто нужно задать атрибуты для генерируемого элемента HTML. Атрибуты задаются в html-хелпере в анонимном классе, через параметр htmlAttributes. Хелперы собирают свойства этих объектов и добавляют их как атрибуты в HTML элементы. Это работает довольно просто, пока вы не начнете использовать зарезервированное слово class или символ тире "-". Все это запрещено использовать в именах свойств объектов. Например, нужно задать атрибут стиля class или любой атрибут, часто используемый при написании скриптов, который начинается с"data-".
Данный код выдаст две синтаксические ошибки.
@Html.ActionLink("Help", "Help", null, htmlAttributes: new { class="special", data-ajax="true"})
Одну проблему можно исправить, используя data_ajax вместо data-ajax, потому что MVC в атрибутах переведет все подчеркивающие символы в тире. Другая проблема решается с помощью символа «@» перед зарезервированным словом.
@Html.ActionLink("Help", "Help", null, htmlAttributes: new { @class="special", data_ajax="true"})
Такой код будет работать без ошибок.
Если ASP.NET MVC приложение использует для генерации страниц только Razor, то имеет смысл убрать генератор WebForms. Иначе MVC, будет периодически проверять наличие файлов с расширениями .aspx и .ascx при поиске представления или шаблона. Это конечно небольшая экономия, но она стоит всего двух команд в начале работы приложения.
ViewEngines.Engines.Clear(); ViewEngines.Engines.Add(new RazorViewEngine());
С помощью оператора @helper можно написать функцию в представлении и там же ее использовать. Функция может выводить текст и содержать блоки кода. Опять необходимо напомнить не злоупотреблять излишним написанием кода в представлениях. Следующий код показывает использование хелпера для вывода текста “В вашей коллекции 3 осьминога” (при условии, что Model.Count = 3)
В вашей коллекции @OctAmount(Model.Count) осьминога. @helper OctAmount(int amount) { <span> @amount </span> }
Если хелпер OctAmount нужен в нескольких представлениях, то лучше определить хелпер в представлении, которое будет находится в папке App_Code.
Для ASP.NET папка App_Code особенная. Во время выполнения приложения в этой папке происходит распознавание кода и компиляция представлений. Но эти представления не работают как обычно, они не наследуются от WebViewPage<T> и их нельзя использовать для генерации HTML страниц. Эти представления наследуются от класса HelperPage и предоставляют public static @helper-функции.
Cоздаем в MVC-проекте папку App_Code, помещаем внутрь представление Helper.cshtml, добавляем туда OctAmount хелпер. Во время выполнения это представление превратится в статический класс Helper, и его можно использовать в любом другом представлении приложения.
В вашей коллекции @Helper.OctAmount(Model.Count) осьминога.
Естественно вы можете определить extension-метод, чтобы сделать хелпер доступным глобально. Такой метод билдится в проект, его легче тестировать и проще упаковать в библиотеку для использования в нескольких проектах. Но с другой стороны в extension-методе тяжелее работать с HTML, тогда как использование C# и HTML в App_Code-представлениях проще и понятнее.
Copyright © CodeHint.ru 2013-2025 (v2.4.7 - работает на Angular Universal)Калькулятор инвест-портфеля