412 000 произведений, 108 200 авторов.

Электронная библиотека книг » Гайдар Магдануров » Asp.net mvc framework » Текст книги (страница 9)
Asp.net mvc framework
  • Текст добавлен: 8 июля 2026, 17:38

Текст книги "Asp.net mvc framework"


Автор книги: Гайдар Магдануров



сообщить о нарушении

Текущая страница: 9 (всего у книги 17 страниц)

Таблица 5.1. Вспомогательные методы класса HtmlHelper

Большая часть вспомогательных методов реализованы как методы-расширения C# 3.0 для класса HtmlHelper (статические методы, определенные вне класса HtmlHelper). Такой подход был избран для того, чтобы разработчики легко могли расширять набор вспомогательных методов в собственных классах и не перегружать сам класс HtmlHelper.

Далее рассмотрено применение каждого из методов, описанных в табл. 5.1. Методы сгруппированы по сходству решаемых задач.

Кодирование текста и атрибутов

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

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

Для кодирования предназначены два вспомогательных метода – Html.AttributeEncode() и Html.Encode().

Пример использования Html.AttributeEncode():

Результирующая разметка:

Пример использования Html.Encode():

<%= Html.Encode(«Текст»)

Результирующая разметка:

TeKCT"


Примечание

Важно отметить, что методы Html.AttributeEncode() и Html.Encode() не заменяют символ апострофа (') на соответствующий HTML-код, поскольку не рекомендуется использовать апострофы для атрибутов тегов на HTML-страницах, хотя это и допустимо с точки зрения HTML-стандарта.

**********************************

Гиперссылки на действия контроллеров


Для создания гиперссылок на действия контроллеров используются два основных вспомогательных метода – Html.ActionLink() и Html.RouteLink().

Html.ActionLink()

Метод Html.ActionLink() применяется для ссылок с использованием строковых значений. Например, для ссылки на действие Index, контроллера Home, именуемой "Главная страница", метод используется следующим образом:

Hnml.ActionLink(«Главная страница», «Index», «Home»)

Результирующая разметка:

<а href="/Home/Index">Главная страница

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

Так, например, если для приложения определен только маршрут

{controller}/{action}/{id}, то следующий вызов метода ActionLink()

Html.ActionLink(«Ссылка», «Data», «Home», new { id = 1, ord = 2 })

приведет к генерации такой ссылки:

Ссылка

Если же среди маршрутов определен, например, и такой {controller}/{action}/{id}/{ord}, то будет сгенерирована следующая ссылка:

Сcылка

Для создания абсолютной ссылки, либо ссылки с дополнительными параметрами, такими как протокол, якорь, также можно воспользоваться методом ActionLink().

Html.ActionLink(«Сайт microsoft.com», «Express», «VStudio»,

  "http", "microsoft.com", "download", new {}, null);

В результате будет создана следующая ссылка:

http://microsoft.com/VStudio/Express#download">

  Сайт microsoft.com


Html. RouteLink()

Метод Html.RouteLink() используется для создания ссылок на основании определенных для приложения маршрутов, о которых подробнее можно узнать в следующей главе. Так, например, можно сослаться на определенный именованный маршрут, передав параметры в виде анонимного объекта.

Html.RouteLink(«Ссылка», «MyRoute»,

  new { action = "hello", id = 1 });

В результате будет создана следующая ссылка, при условии, что маршрут SomeRoute определен как mycontroller/{action}/sometext/{id}.

Сcылка

Элементы управления HTML-страницы


Большая часть вспомогательных методов, приведенных в табл. 5.1, связаны с созданием HTML-разметки для элементов ввода данных HTML-форм. В этой части главы мы рассмотрим их применение.

HTML-форма

Для того чтобы данные, введенные пользователем в элементы управления, были корректно отправлены на сервер и обработаны ожидающим этих данных действием контроллера, необходимо создать тег

, для этого существует вспомогательный метод Html.BeginForm(действие контроллера, имя контроллера). Если при вызове метода не указаны параметры, атрибут action тега будет заполнен текущим URL.

<% using(Html.BeginForm(«About», «Home»)){ %>

<% } %>

В примере используется синтаксис using(){}. Дело в том, что метод Html.BeginForm() возвращает объект, реализующий интерфейс IDisposable. Метод Dispose() этого объекта определен таким образом, чтобы выводить закрывающий тег формы

. Вместо синтаксиса using(){} можно воспользоваться вспомогательным методом Html. EndForm().

<% Html.BeginForm(«About», «Home»); %>

<% Html.EndForm (); %>

Синтаксис using(){} удобнее при наличии нескольких независимых форм на странице – в этом случае формы будут выглядеть визуально обособленно.

При отображении представления будет создана соответствующая разметка для тега

.

В случае необходимости задать дополнительные параметры URL, по которому будут отправлены данные формы, необходимо передать анонимный объект, свойства которого будут преобразованы в пары ключ-значение. Для определения метода отправки формы, в качестве параметра нужно передать значение перечислимого FormMethod.

<% using (Html.BeginForm(«About», «Home»,

   new { hello = "world", answer = 42 }, FormMethod.Get )) { %>

<% } %>

Эти параметры будут использованы при генерации тега

.


Текстовые поля, скрытые поля и кнопки

Вспомогательные методы для генерации текстовых полей, скрытых полей и кнопок работают по общему принципу – первым параметром передается идентификатор, который будет использован для создаваемого HTML-элемента и на основании которого сопоставляется значение элемента управления и создается пара ключ-значение при отправке данных формы на сервер.

<%= Html.TextArea(«myText», «Hello world!») %>

В отличие от метода Html.BeginForm, выводящего строковые значения непосредственно в выходной буфер ответа пользователю, вспомогательные методы элементов управления возвращают строку, поэтому для них нужно использовать синтаксис <%= %>. Тогда в разметку страницы будет выведена соответствующая строка.

Для создания дополнительных атрибутов вспомогательным методам необходимо передать анонимный объект.

<%= Html.TextBox(«myTextBox», «„, new { style=“color: yellow;»,

  @class="helloWorld" })%>

Поскольку в качестве имени свойства анонимного объекта нельзя использовать зарезервированные ключевые слова языка C#, то перед такими именами свойств нужно добавить символ @. В результирующий вывод свойство @class войдет как class, без символа @.

   name="myTextBox" style="color: yellow;" type="text" value="" />

Особым случаем является вспомогательный метод Html.CheckBox, поскольку он создает два HTML-элемента управления. Непосредственно элемент «флажок» и «скрытое поле».

<%= Html.CheckBox(«myCheckBox», true) %>

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

  type="checkbox" value="true" />

Стоит отметить, каким образом присваиваются значения элементам управления. При генерации разметки для элемента управления myTextBox механизм представления сначала проверит наличие значения в коллекции ViewData.ModelState для элемента с именем myTextBox: ViewData.ModelState["myTextBox"].Value.RawValue, затем будет использовано значение, переданное в качестве параметра вспомогательному методу. В случае если вспомогательному методу не было передано параметров, то будет осуществлена попытка найти значение в коллекции ViewData: ViewData.Eval(«myTextBox»). Подробнее о коллекции ModelState рассказано в разделе, посвященном проверке значений элементов управления.

Элементы-списки

Для генерации списков используются два метода Html.DropDownList() и Html.ListBox(), генерирующие разметку для элементов: управления "выпадающий список" и "список" соответственно. Оба этих вспомогательных метода принимают в качестве параметра коллекцию SelectList.

<%= Html.DropDownList(«lstName»,

  new SelectList( new[] {"John", "Paul", "George", "Rringo"} )) %>

В результате создается разметка, содержащая теги

Для обеспечения возможности выбора нескольких элементов в списках, генерируемых методом ListBox, в качестве параметра следует передать коллекцию MultiSelectList.

<%= Html.ListBox(«lstName»,

  new MultiSelectList( new[] {"John", "Paul", "George", "Rringo"} )) %>

Тогда будет определено свойство multiple тега

 

 

 

 

Разумеется, в реальных приложениях не всегда удобно создавать отдельно список для элементов форм и хотелось бы использовать коллекцию бизнесобъектов, применяемых в логике приложения. Для этого может быть использован конструктор коллекции SelectList.

SelectList(коллекция объектов,

  название поля объекта,  содержащее значение,

  название поля объекта, содержащее текст,

  выбранное значение

)

Например, в нашем приложении используются объекты типа Person, определение которых представлено далее.

public class Person {

  public int Id { get; set; }

  public string Name { get; set; }

}

Тогда в методе контроллера для сохранения в коллекцию ViewData коллекцию элементов списка можно передать, используя конструктор SelectList так, как показано далее.

public ActionResult About()

{

  List lst = new List

  {

    new Person { Id = 1, Name = "John"},

    new Person { Id = 2, Name = "Paul"},

    new Person { Id = 3, Name = "George"},

    new Person { Id = 4, Name = "Ringo"}

  };

  ViewData["lstName"] = new SelectList(lst, "Id", "Name", 2);

  return View () ;

}

В результате будет создана HTML-разметка, приведенная далее.

Таким образом, коллекция бизнес-объектов может быть использована для заполнения списков необходимыми данными.

Индикаторы корректности введенных данных

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

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

Листинг 5.7. Пример валидации данных

[AcceptVerbs(HttpVerbs.Post)]

public ActionResult Edit(Product obj, int id)

{

  if (obj.UnitsOnOrder < 0)

    ModelState.AddModelError("UnitsOnOrder",

         "Количество заказанных единиц товара не может

          быть отрицательным.");

  if (obj.UnitsInStock < 0)

    ModelState.AddModelError("UnitsInStock",

          "Количество единиц товара на складе должно быть не

          отрицательным.");

  if (obj.UnitPrice <= 0)

    ModelState.AddModelError("UnitPrice",

          "Цена должна быть больше нуля.");

  if (!ModelState.IsValid)

  {

    // есть ошибки, еще раз

    // показать форму редактирования

    return View(obj);

  }

  else

  {

    // ошибок нет, сохранить

    db.SaveProduct(obj);

    return RedirectToAction("Index");

  }

}

Процесс валидации прост – выполняется проверка условий и в случае наличия ошибок в коллекцию Modelstate добавляется информация в виде пары «идентификатор элемента – описание допущенной ошибки». Если в коллекцию Modelstate добавлена хотя бы одна такая пара, то значение свойства Modelstate.isValid будет установлено в false. В случае если ошибки допущены, то необходимо снова отобразить то же представление, которое использовалось для радактирования данных, и передать ему те данные, которые были введены пользователем на предыдущем шаге. Пример такого представления, работающего с кодом, описанным в листинге 5.7, показан в листинге 5.8, там же приведено строго типизированное представление, в качестве модели использующее класс Product.

Листинг 5.8. Представление Edit.aspx

<%@ Page Title="" Language="C#"

        MasterPageFile="~/Views/Shared/Site.Master"

        Inherits="System.Web.Mvc.ViewPage" %>

                    runat="server">

  Edit

 

    Редактирование сведений о товаре

 

  <%= Html.ValidationSummary("npи редактировании сведений

                    о товаре произошли ошибки.") %>

  <% using (Html.BeginForm())

  {%>

   

      Редактирование сведений о товаре

     

       

          Код продукта:

       

        <%= Model.ProductID.ToString() %>

        <%= Html.Hidden("ProductId", Model.ProductID)%>

     

      

        

          Название:

       

        <%= Html.TextBox("ProductName", Model.ProductName) %>

        <%= Html.ValidationMessage("ProductName", "*") %>

     

      

       

          Цена:

        

        <%= Html.TextBox("UnitPrice",

               String.Format("{0:F}", Model.UnitPrice)) %>

        <%= Html.ValidationMessage("UnitPrice", "*") %>

      

     

       

          На складе:

       

        <%= Html.TextBox("UnitsInStock", Model.UnitsInStock) %>

        <%= Html.ValidationMessage("UnitsInStock", "*") %>

     

      

       

          Заказано:

       

        <%= Html.TextBox("UnitsOnOrder", Model.UnitsOnOrder) %>

        <%= Html.ValidationMessage("UnitsOnOrder", "*") %>

      

     

       

     

    

  <% } %>

 

    <%=Html.ActionLink("K списку товаров", "Index") %>

 

В листинге 5.8 методы Html.ValidationMessage() вызываются co вторым строковым параметром, указывающим сообщение, которое должно быть отображено пользователю в случае наличия ошибки в коллекции ModelState. В результате форма, заполненная с ошибками, будет выглядеть так, как показано на рис. 5.2.

Для того чтобы сообщение об ошибке было выведено непосредственно в месте вызова метода Html.ValidationMessage(), метод нужно вызывать без указания второго параметра Html.ValidationMessage("UnitPrice"). Результат приведен на рис. 5.3.

Стоит отметить, что если в коде представления не используется строготипизированная привязка к свойствам модели, то привязка к данным осуществляется автоматически, и в этом случае при возникновении ошибок нет необходимости передавать объект модели представлению через метод View(), как это было сделано в листинге 5.7. То есть фрагмент кода из листинга 5.7 может быть написан так, как указано далее. Листинг 5.9 демонстрирует код представления, не использующего привязку к свойствам объекта модели Model.

if (IModelState.IsValid)

{

  // есть ошибки, еще раз

  // показать форму редактирования

  return View();

}

Листинг 5.9. Представление Edit.aspx без привязки к свойствам объекта Model

<%@ Page Title="" Language="C#"

        MasterPageFile="~/Views/Shared/Site.Master"

        Inherits="System.Web.Mvc.ViewPage" %>

  Edit

 

    Редактирование сведений о товаре

 

  <%= Html.ValidationSummary("при редактировании сведений

                   о товаре произошли ошибки.") %>

  <% using (Html.BeginForm())

  {%>

   

      Редактирование сведений о товаре

     

       

          Код продукта:

        

        <%= ViewData.Eval("ProductID") %>

        <%= Html.Hidden("ProductID")%>

      

     

       

          Название:

       

        <%= Html.TextBox("ProductName") %>

        <%= Html.ValidationMessage("ProductName") %>

     

     

       

          Цена:

       

        <%= Html.TextBox("UnitPrice") %>

        <%= Html.ValidationMessage("UnitPrice") %>

     

      

       

          На складе:

       

        <%= Html.TextBox("UnitsInStock") %>

        <%= Html.ValidationMessage("UnitsInStock") %>

     

     

       

          Заказано:

       

        <%= Html.TextBox("UnitsOnOrder") %>

        <%= Html.ValidationMessage("UnitsOnOrder") %>

     

     

        

      

   

  <% } %>

 

    <%=Html.ActionLink("K списку товаров", "Index") %>

  


Примечание

Важно обратить внимание, что при использовании кода, аналогичного приведенному в листинге 5.9, поиск значений элементов формы будет осуществляться через ViewData.Eval(), и значение ViewData["SomeProperty"] имеет больший приоритет, чем ViewData.Model.SomeProperty. Поэтому, во избежание трудноуловимых ошибок, при создании кода контроллера стоит с особенной тщательностью относиться к тому, как передаются данные – через свойства объекта-модели или через коллекцию ViewData.

***************************

Создание собственного вспомогательного метода


Поскольку вспомогательные методы – обычные методы расширения класса HtmlHelper, принимающие произвольный набор параметров и возвращающие строковые значения, то создать свой вспомогательный метод не составляет труда. Например, в листинге 5.10 приведена заготовка вспомогательного метода, отображающего элемент управления для ввода даты.

Листинг 5.10. Вспомогательный метод для отображения элемента для ввода даты

using System.Web.Mvc;

public static class DataPickerHelper {

  public static string DatePicker(this HtmlHelper html,

          string id, string text)

  {

  }

}

Такой метод может быть использован в коде представления через синтаксис

<%= Html.DatePicker(«id», «name») %>.

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

Конкатенация строк

Самый очевидный способ – сгенерировать разметку конкатенацией строк. Код для этого метода приведен в листинге 5.11.

Листинг 5.11. Реализация метода DatePickerc помощью конкатенации строк

using System.Web.Mvc;

using System.Text;

using System;

using System.Globalization;

public static class DataPickerHelper

{

  public static string DatePicker(this HtmlHelper html, string id)

 {

    return DatePicker(html, id, String.Empty);

  }

  public static string DatePicker(this HtmlHelper html,

                  string id, string text)

  {

    StringBuilder sb = new StringBuilder();

    if (!String.IsNullOrEmpty(text))

    {

      sb.Append("

      sb.Append (id);

      sb.Append("">");

      sb.Append(text);

    }

    /* Day */

    sb.Append("");

      sb.Append(" ");

    }

    /* Month */

    sb.Append("");

    sb.Append(" ");

    /* Year */

    sb.Append("");

    if (!String.IsNullOrEmpty(text))

    {

      sb.Append("

");

    }

    return sb.ToString();

  }

}

Плюс решения, продемонстрированного в листинге 5.11, – простота реализации «в лоб», копированием кода из макета верстки. Минусы решения очевидны – поддержка такого кода сложна за счет необходимости работы с кодом, перемешанным с большим количеством строковых констант.

Использование ресурсов

Упростить модификацию самой разметки и внесение в нее косметических изменений можно за счет размещения статических строковых констант в файлах ресурсов. Генерацию финальной разметки при этом можно выполнять, используя только методы форматирования строк, как это показано в листинге 5.12.

Листинг 5.12. Реализация метода DatePickerc помощью ресурсов

public static string DatePicker(this HtmlHelper html,

                           string id, string text)

{

  return String.Format(Resources.DatePicker, id, text,

                Resources.DaysOptions,

                Resources.MonthsOptions, Resources.YearsOptions);

}

В приведенном фрагменте есть заметное преимущество – централизованное управление разметкой, возможность использования разной разметки для различных культур и разделение самой разметки и кода. Можно пойти дальше и создать дополнительную обертку над ресурсами, которая будет отвечать за небольшую модификацию фрагментов разметки. Кода в случае, приведенном в листинге 5.12, значительно меньше, чем в листинге 5.11, однако гибкость такого решения может быть недостаточной для вспомогательных методов, требующих частой модификации.

Использование дополнительных слоев абстракции

Достигнуть большего контроля над логикой и разметкой можно за счет использования дополнительной абстракции над созданием самой разметки, вынесением отдельных методов, генерирующих повторяющие элементы, и созданием тегов с помощью специального класса TagBuilder. В WebForms при создании контролов (Custom Controls) используется похожий подход.

TagBuilder активно применяется в расширениях, входящих в саму сборку System.Web.Mvc, в чем можно убедиться, посмотрев, например, на исходный код System.Web.MVC.SelectExtensions.

В листинге 5.13 приведен код, использующий больше абстракции, нежели предыдущие. Также в листинге 5.13 продемонстрирована простая концепция по восстановлению значений после отправки данных на сервер (метод Getvalue, выполняющий поиск в коллекции viewData, затем в параметрах запроса).

Листинг 5.13. Реализация метода DatePicker с дополнительными слоями абстракции

public static class DataPickerHelper

{

  private static string DAY_PREFIX = "day_";

  private static string MONTH_PREFIX = "month_";

  private static string YEAR_PREFIX = "year_";

  private static string ListItemToOption(SelectListItem item)

  {

    TagBuilder builder = new TagBuilder("option")

    {

      InnerHtml = HttpUtility.HtmlEncode(item.Text)

    };

    if (item.value != null)

      builder.Attributes["value"] = item.Value;

    if (item.Selected)

      builder.Attributes["selected"] = "selected";

    return builder.ToString(TagRenderMode.Normal);

}

private static string SelectList(string id,

                             List items)

{

  StringBuilder listItemBuilder = new StringBuilder();

  foreach (var item in items)

  {

    listItemBuilder.AppendLine(ListItemToOption(item));

  }

  TagBuilder tagBuilder = new TagBuilder(«select»)

  {

    InnerHtml = listItemBuilder.ToString()

  };

  tagBuilder.Attributes.Add(«id», id);

  tagBuilder.Attributes.Add("name", id);

  return tagBuilder.ToString(TagRenderMode.Normal);

}

  public static string DatePicker(this HtmlHelper html, string id)

  {

    return DatePicker(html, id, String.Empty);

  }

  public static string DatePicker(this HtmlHelper html,

                                string id, string text)

  {

    // buffer

    StringBuilder sb = new StringBuilder();

    // generate days

    List days = new List();

    string dayValue = GetValue(html, DAY_PREFIX + id);

    for (int i = 0; i <= 31; i++)

    {

      days.Add(new SelectListItem

      {

        Text = (i == 0) ? String.Empty : i.ToString(),

        Value = i.ToString(),

        Selected = (dayValue == i.ToString())

      });

    }

    sb.AppendLine(SelectList(DAY_PREFIX + id, days));

    // generate months

    List months = new List();

    string monthValue = GetValue(html, MONTH_PREFIX + id);

    for (int i = 0; i <= 12; i++)

    {

      months.Add(new SelectListItem

      {

        Text = (i == 0) ? String.Empty :

           DateTimeFormatInfo.CurrentInfo.MonthNames[i – 1],

        Value = i.ToString(),

        Selected = (monthValue == i.ToString())

      });

    }

    sb.AppendLine(SelectList(MONTH_PREFIX + id, months));

    // generate years

    List years = new List();

    string yearValue = GetValue(html, YEAR_PREFIX + id);

    for (int i = 1900; i <= DateTime.Now.Year; i++)

    {

      years.Add(new SelectListItem

      {

        Text = (i == 1900) ? String.Empty : i.ToString(),

           Value = i.ToString(),

        Selected = (yearValue == i.ToString())

      });

    }

    sb.AppendLine(SelectList(YEAR_PREFIX + id, years));

    // parent tag

    if (!String.IsNullOrEmpty(text))

    {

      TagBuilder div = new TagBuilder("div");

      div.Attributes.Add("id", id);

      div.InnerHtml = text + sb.ToString();

      sb = new StringBuilder(

              div.ToString(TagRenderMode.Normal));

    }

    return sb.ToString();

  }

  private static string GetValue(HtmlHelper html, string id)

  {

    object o = null;

    if (html.ViewData != null)

      o = html.ViewData.Eval(id);

    if (o == null)

      o = html.ViewContext.RequestContext.HttpContext.Request.Params[id];

    return (o == null) ? String.Empty : o.ToString();

  }

}

Использование серверных элементов управления WebForms

В главе 2, в разд. "Использование элементов управления WebForms в MVC-приложениях” уже была продемонстрирована возможность применения серверных элементов управления в представлениях MVC. Как уже было сказано ранее, использование серверных элементов управления может быть оправдано, если не требуется интерактивное взаимодействие с соответствующим элементом, и он используется только для генерации разметки.

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

Сделать это можно просто, учитывая, что класс Webcontrol, которому наследуют классы конкретных элементов управления, содержит метод Render(), генерирующий разметку. Как раз метод Render() применяет инфраструктура WebForms для всех элементов управления на страницах. Пример использования элемента управления WebForms приведен в листинге 5.14.

Листинг 5.14. Пример использования класса Button во вспомогательном методе

public static class WebFormsHelper {

  public static string WebFormsButton(this HtmlHelper html)

  {

    Button control = new Button { Text = "Web Forms Button" };

    StringBuilder sb = new StringBuilder();

    HtmlTextWriter htmlWriter = new HtmlTextWriter(

                                 new StringWriter(sb));

    control.RenderControl(htmlWriter);

    return sb.ToString();

  }

}

Листинг 5.14 демонстрирует концепцию использования серверных элементов управления: создать экземпляр класса элемента управления, задать его свойства, вызвать при необходимости методы, а затем сгенерировать разметку, которая будет возвращена вспомогательным методом.

В каких случаях подобный подход к использованию серверных элементов управления может быть оправдан? В случаях, когда у вас есть существующий элемент управления, отвечающий вашим требованиям, и для которого подобная обертка может быть удобной в использовании. Универсального рецепта для принятия решения, стоит ли использовать элемент управления подобным образом, – нет, однако имеет смысл задуматься в случае, когда для элемента управления приходится эмулировать серверные события. Зачастую в подобных ситуациях проще реализовать поддержку необходимой функциональности в самих вспомогательных методах.

Частичные представления


Ранее в этой главе уже говорилось об использовании частичных представлений. Механизм частичных представлений позволяет многократно использовать разметку в разных методах контроллеров, аналогично примеру из листингов 5.1—5.3. Кроме того, частичные представления могут быть использованы для отображения списков элементов. Так, в листинге 5.15 приведено частичное представление, которое используется для отображения строк таблицы товаров в представлении Index.aspx, код которого приведен в листинге 5.16.

Листинг 5.15. Частичное представление ProductListItem.ascx


    Ваша оценка произведения:

Популярные книги за неделю