Совершенствуем работу с представлениями Razor

| Понедельник, 18 февраля, 2013

Метки: Razor, ASP.NET MVC Комментарии: 0

Блоки c кодом и переменные

В 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. Атрибуты задаются в 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"})

Такой код будет работать без ошибок.

Удаление генератора представлений WebForms

Если 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>
}

App_Code-хелперы

Если хелпер 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-2019