Описание языка разметки .NetRazor

Razor – новый механизм визуализации в ASP.NET

Внимание!Если вы практически не сталкивались напрямую с языком разметки HTML, то ознакомиться с ним можно здесь.

Razor позволяет вам начать со статического HTML (или любого текстового содержимого), далее делая его динамическим, добавляя серверный код. Одна из основных целей проектирования Razor – предоставить гибкий процесс кодирования и позволить быстро интегрировать серверный код в HTML-разметку с минимумом усилий. Проще говоря, Razor – это совместное использование разметки HTML и языка программирования C# в представлении (View).

Важно! Если вы не сталкивались с MVC (Model-View-Controller), ознакомиться с ними можно также перейдя по этой ссылке.

Razor – является механизмом визуализации модели MVC, а точнее View (представления). В данной статье описаны основы синтаксиса Razor.

Что такое Razor?

Razor создан на основе ASP.NET и предназначен для создания веб-приложений. Он обладает функциями традиционной ASP.NET-разметки, но проще в использовании.

Razor – синтаксис разметки, позволяющий встраивать серверный код (Visual Basic и C #) в веб-страницы.

Серверным кодом можно создавать динамический веб-контент. Пользователь делает что-то в браузере, браузер отправляет запрос, сервер его обрабатывает. На основе данных от браузера сервер интерпретирует соответствующий файл на Razor, в результате получается новая страница или её фрагмент на HTML. Сгенерированный HTML отправляется в браузер и отображается пользователю. Объём кода необходимый для описания одной страницы на Razor в несколько раз меньше аналогичного объёма на HTML. Razor выполняет часть задач, которые обычно приходится писать на javascript (а для этого требуется специалист со знанием уже 2 языков программирования). Razor может обращаться к базам данных, выполнять несложные (или довольно сложные) операции с данными для отображения их пользователю.

 

Синтаксис Razor

Razor –  это вставки C# внутри HTML разметки. Каждая строка C# начинается с символа @. 

Используется синтаксис очень похожий на PHP и классический ASP.

Razor:

@for (int i = 0; i < 10; i++) {
 <li>@i</li>
 }

PHP:

<ul>
<?php 
for ($i = 0; $i < 10; $i++) {
echo("<li>$i</li>");
} 
?>
</ul>

Классический ASP:

<ul>
<% for (int i = 0; i < 10; i++) { %>
<li><% =i %></li>
<% } %>
</ul> 
 

Все три примера на выходе дают список из 10 элементов, но невооружённым глазом видно, что фрагмент кода на Razor короче остальных. Краткость и есть ключевое преимущество данного синтаксиса. Чем короче код, тем проще с ним работать.

Основные правила синтаксиса Razor 

 Razor – это C# в HTML, и синтаксис почти полностью идентичен чистому C#:

  • блоки Razor кода заключены в @ {... };
  • встроенные выражения (переменные и функции) начинаются с @;
  • строка кода заканчивается точкой (не всегда, но это не так важно);
  • переменные объявляются с ключевым словом Var (но возможна и строгое объявление типа переменой);
  • строки заключены в кавычки;
  • в C# коде учитывается регистр;
  • Razor файлы имеют расширение .cshtml (C# смешанный с HTML).

C# Пример

<!-- Single statement block -->
@{ var myMessage = "Hello World"; }

<!-- Inline expression or variable -->
<p>The value of myMessage is: @myMessage</p> 

<!-- Multi-statement block -->
@{
var greeting = "Welcome to our site!";
var weekDay = DateTime.Now.DayOfWeek;
var greetingMessage = greeting + " Here in Huston it is: " + weekDay;
}
<p>The greeting is: @greetingMessage</p>

Переменные

Переменные используются для хранения какой-либо информации, данных.

Имя переменной начинается со строчной буквы, не может содержать пробелы или зарезервированные символы. Имена переменных принято писать на английском языке, использование транслитерации считается дурным тоном. Если название состоит из нескольких слов, они записываются слитно без пробелов, причем каждое слово, кроме первого, начинается с прописной буквы, например: someStringVariable. Переменная имеет определенный тип. C# – строго типизированный язык, и без преобразования типа переменной типа Строка присвоить переменную типа Число невозможно (в PHP или JavaScript это вполне возможно, так как они не являются строго типизированными). Существуют строковые переменные ("Добро пожаловать"), целое число (103), дата и т.д. типов данных в C# много. Переменные объявляются с помощью ключевого слова var (с маленькой буквы, как и все ключевые слова в C#) и имени (var someStringVariable;), или с помощью типа (String someStringVariable;). Если использовано ключевое слово var, то переменной в первый раз можно присвоить значение любого типа. Потом тип переменной определится, и его нельзя будет изменить без операций преобразования типа. Если тип указан сразу, то его тоже нельзя изменить без преобразования типа, если оно возможно. 

Примеры

// Using the var keyword:
var greeting = "Welcome to W3Schools";
var counter = 103;
var today = DateTime.Today;
// Using data types:
string greeting = "Welcome to W3Schools";
int counter = 103;
DateTime today = DateTime.Today;

Типы данных

Ниже приведен список наиболее распространенных типов данных:

Тип

Описание

Пример

int

Integer (целое число)

103, 12, 5168

float

Число с плавающей точкой

3.14, 3.4e38

decimal

имеет более точный и узкий диапазон удобен для финансовых рассчётов

1037.196543

bool

Логическое значение

true, false

string

Строка

"Hello W3Schools", "Привет"

 Подробнее о типах данных в C# http://msdn.microsoft.com/ru-ru/library/cs7y5x0x(v=vs.90).aspx

Операторы

Оператор сообщает какие команды необходимо выполнять в выражении. Большинство операторов можно посмотреть, перейдя по этой ссылке.

Циклы

Существует четыре оператора циклов: два из них на основе while, два – на основе for. Рассмотрим подробнее циклы for и foreach. Цикл for принимает 3 параметра for (переменная счётчик, условие выхода, изменение переменной счётчика): for(int i=0;i>=10;i++){действия}. Здесь переменная счётчик int i ноль, условие завершения – счётчик больше 10, изменение счётчика – операция увеличения на 1 (оператор ++). В примере ниже приведено несколько другое использование for.

Пример

<html>
<body>
@for(var i = 10; i < 21; i++)
    {<p>Line @i</p>}
</body>
</html>

Работа с коллекциями

В работе с коллекцией или массивом часто используется цикл foreach

Коллекция представляет собой группу однотипных объектов, и с каждым из них внутри тела foreach можно работать отдельно. Наиболее часто встречается коллекция типа List – это динамический массив. В отличие от обычного массива с заданным при создании количеством элементов, динамический массив List сам по мере необходимости увеличивает свою длину. Кроме List, часто встречается Dictionary (словарь). В словаре хранятся элементы выпадающего списка. Каждый элемент словаря – это не просто значение, а пара значений Ключ (key) и Значение (value). Есть и другие типы коллекций. Цикл foreach обходит коллекцию с первого до последнего элемента. Он будет работать до тех пор, пока не дойдет до последнего элемента, либо не выполнится какое-либо условие выхода, либо не встретится оператор break.

Пример цикла с коллекцией

<html>
<body>
<ul>
@foreach (var x in Request.ServerVariables)
    {<li>@x</li>}
</ul>
</body>
</html>

Условия или ветвления

Условия или ветвления являются одной из ключевых конструкций в традиционных языках программирования. В C# условный оператор состоит из двух блоков if(){} и else{}. В круглых скобках при if ставится условие. Условие – это логическая переменная или выражение, результатом которого является логическая переменная. Если значение условия true (истина), то выполняются операторы в первом блоке между фигурными скобками, если false (ложь), то во втором. Блок else может отсутствовать, и тогда в случае условия false, блок операций при if будет пропущен.  

  

@{var price=50;}
<html>
<body>
@if (price>30)
    {
    <p>The price is too high.</p>
    }
</body>
</html>
@{var price=20;}
<html>
<body>
@if (price>30)
  {
  <p>The price is too high.</p>
  }
else
  {
  <p>The price is OK.</p>
  } 
</body>
</html>

Оператор switch

Блок переключателей (switch) используется, если вариантов много. Cоздавать больше двух операторов if не рекомендуется. Типичный пример использования switch – ситуация, когда в зависимости от дня недели должны происходить разные действий. Switch работает следующим образом: в круглых скобках при switсh() указывается переменная, которая может принимать известное множество значений (дни недели), далее в фигурных скобках {} идёт ряд операторов case (значение) – это значения из множества значений переменной при switch. Каждый раз при заходе в switch выбирается нужный case. Каждый case содержит блок операторов, обязательно заканчивающийся оператором break. Если по какой-то причине переменная не содержит ни одного значения из предусмотренных в case, срабатывает ветка defalt: в ней не предусмотрено значения, и она выполняет часто значительно отличающиеся от остальных веток действия. Не является обязательной. Ставится для принятия решения в нестандартном случае или в любых случаях, не рассматриваемых в case.

Пример

@{
var weekday=DateTime.Now.DayOfWeek;
var day=weekday.ToString();
var message="";
}
<html>
<body>
@switch(day)
{
case "Monday":
    message="This is the first weekday.";
    break;
case "Thursday":
    message="Only one day before weekend.";
    break;
case "Friday":
    message="Tomorrow is weekend!";
    break;
default:
    message="Today is " + day;
    break;
}
<p>@message</p>
</body>
</html>

На этом обзор языка C# завершён. При написании разметки Razor часто встречается весьма удобный класс HTML, благодаря его методам Html.EditorOrDisplay(),  Html.Caption()Html.Description()Html.EditableProperty() и многим другим удобно генерируется различные элементы html-разметки. В этих методах удобно подставляются данные и настройки отображения. Далее приведён пример, как сделать поле обязательным для заполнения.

Пример

@Html.EditableProperty("Genpodryadchik", a => {a.Container("div"); a.Required = true;})

 a => {a.Container("div"); a.Required = true;}

 

этот фрагмент кода называется лямбда-выражение, буква a не является обязательной. Можно использовать любую другую. Таким образом, может быть выставлено более двух параметров из тех, которые есть у объекта EditableProperty. Именно он представлен символом а в лямбда-выражении.

 

В завершение статьи более масштабный фрагмент разметки на Razor 

@using (var data = new ObjectViewData(this))
{
<tr>
<td colspan="1">
<div style="float:left;">
@Html.Caption("Genpodryadchik", a => a.Container("div"))
@Html.EditableProperty("Genpodryadchik", a => {a.Container("div"); a.Required = true;})
@Html.Caption("Zakazchik", a => a.Container("div") )
@Html.EditableProperty("Zakazchik", a => {a.Container("div"); a.Required = true;})
@Html.Caption("Zastroyschik", a => a.Container("div"))
@Html.EditableProperty("Zastroyschik", a => {a.Container("div"); a.Required = true;})
</div>
</td>
</tr>
}

он создаёт три поля с подписями, поля помечены обязательными для заполнения. 

Пример создания портлета типа Код. В портлет будут подгружаться 10 новостей из новостной ленты определённого ресурса в сети. Можно использовать любую внешнюю ссылку. Главное, чтобы по ней загружался xml такой же или аналогичной структуры.

@using System.Xml; // пространства имён для работы с xml web-ом и вводом выводом(используется потоковая загрузка и обработка, без сохранения в файл)
@using System.Net;
@using System.IO;
<h1>Новости</h1>// все html вставки будут выведены на портлет
@{

      // отправка запроса 
      HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.cbr.ru/scripts/XML_News.asp");

      // запрос ответа
      HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

       // поток данных ответа
      Stream stream = resp.GetResponseStream();

      // создание xmlReadera для данных из потока ответа
      var xr = XmlReader.Create(stream);

      // создание переменных для данных
      string date = null;
      string content = null;
      int counter = 1;// счётчик для вывода опредлённого колличества новостей

      // цикл с пред условием условие пока xml не кончился и пока счётчик не равен 11
      while (xr.Read() && counter!=11)
      { 

         // выбираем нужные фрагменты данных и собираем из них блоки новостей. 

         if(xr.Name == "Date")
         {
            date = xr.ReadElementContentAsString(); 
         }
         if(xr.Name == "Url" && date != null)
         {
            <p>Новость от: @date.ToString() <a href = @xr.ReadElementContentAsString();>Новость @counter.ToString() </a> </p> 
         }
         if(xr.Name == "Title") 
         {
            content = xr.ReadElementContentAsString(); 
            <p> @content </p>

            counter++;

   }

   }
}

а так это выглядит в действии 

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

@using (var data = new ObjectViewData(this))
{
   <tr> 
       <td>
           <div style="float: left; width: 300px;"> 
                 @Html.Caption("FIO", a => { a.Container("div");})
                 @Html.EditorOrDisplay("FIO", a => { a.Container("div");})
           </div>
       </td>
   </tr>
   <tr>
         <td>
              <div style="float: left; width: 100px; margin: 10px;">
                      @Html.Caption("Marka", a => { a.Container("div");})
                      @Html.EditorOrDisplay("Marka", a => { a.Container("div");})
               </div> 
               <div style="float: left; width: 100px; margin: 10px;">
                      @Html.Caption("Modelj", a => { a.Container("div");})
                      @Html.EditorOrDisplay("Modelj", a => { a.Container("div");})
               </div>
               <div style="float: left; width: 100px; margin: 10px;">
                       @Html.Caption("GodVypuska", a => { a.Container("div");})
                       @Html.EditorOrDisplay("GodVypuska", a => { a.Container("div");})
               </div>
               <div style="float: left; width: 100px; margin: 10px;">
                        @Html.Caption("Probeg", a => { a.Container("div");})
                        @Html.EditorOrDisplay("Probeg", a => { a.Container("div");})
              </div>
         </td>
   </tr>
   <tr>
       <td> 
             <div style="float: left; width: 100px; margin: 3px;">
                    @Html.Caption("TipTS", a => { a.Container("div");})
                    @Html.EditorOrDisplay("TipTS", a => { a.Container("div");})
            </div>
         </td>
     </tr>
     <tr>
         <td> 
              <div style="float: left; width: 100px; margin: 3px;">
                        @Html.Caption("MestoPriobreteniya", a => { a.Container("div");})
                        @Html.EditorOrDisplay("MestoPriobreteniya", a => { a.Container("div");})
                 </div>
            </td>
        </tr>
        <tr>
            <td> 
                 <div style="float: left; width: 100px; margin: 3px; bgcolor: #aaa">
                        @Html.Caption("SummaStrahovaniya", a => { a.Container("div");})
                        @Html.EditorOrDisplay("SummaStrahovaniya", a => { a.Container("div");})
                 </div>
             </td>
       </tr> 
}

Полезные ссылки по теме:

Использование синтаксиса Razor в ASP.net - http://www.asp.net/web-pages/overview/getting-started/introducing-razor-syntax-(c)

Класс HtmlHelper - http://msdn.microsoft.com/ru-ru/library/system.web.mvc.htmlhelper(v=vs.118).aspx