4. В случае провала предыдущих попыток поиска будут проверены свойства объекта Model: ViewData.Model.customer.lastname и ViewData.Model.customer["lastname"].
Описанный ранее метод поиска приводит к нескольким выводам — при поиске элементы коллекции viewData имеют приоритет над свойствами объекта, передаваемого через свойство в Model, поэтому следует не допускать совпадения именований свойств объекта, передаваемого через Model и элементов коллекции ViewData.
Использование метода viewData.Eval несет в себе также и возможность передавать строку для форматирования вывода данных.
<%= ViewData.Eval("customer.regDate", "Клиент с {0:yyyy} года.") %>
Метод viewData используется внутренней инфраструктурой MVC Framework для связывания данных с полями ввода и вывода информации о проверке корректности данных, о чем подробнее будет рассказано далее в этой главе вразд. "Валидация данных форм”.
Генерация разметки представлением
Для создания логики генерации представления в MVC Framework используются несколько подходов.
□ Вложенный управляющий код. Логика отображения данных описывается непосредственно внутри файла разметки ASPX с использованием стандартного синтаксиса <% %> для управляющих конструкций и синтаксиса <%= %> для вывода строковых значений непосредственно в результирующий код разметки.
□ Вспомогательные методы для генерации разметки. Вспомогательные методы позволяют многократно использовать фрагменты логики генерации представления и представляют собой вызовы некоторых методов, возвращающих строки. В библиотеке MVC Framework существует большой набор готовых вспомогательных методов, представленных как методы-расширения для классов Html, Url, Ajax, однако в качестве вспомогательного метода может быть использован любой метод, возвращающий строковое значение.
□ Серверные элементы управления. Несмотря на отсутствие возможности использования событийной модели, серверные элементы управления ASP.NET по-прежнему могут быть использованы для декларативного отображения данных.
Примечание
На самом деле в приведенном ранее списке присутствует немного лукавства, поскольку, по большому счету, генерация представлений в конечном итоге основывается на создании компилируемого управляющего кода.
Рассмотрим каждый из подходов подробно на практическом примере, и по мере изложения материала будем создавать работающее демонстрационное приложение, использующее разобранные ранее возможности.
*****************************************
Вложенный управляющий код
Рассмотрим простейший пример — в представлении необходимо вывести таблицу, содержащую набор записей, переданных контроллером через коллекцию viewData. В качестве источника данных используется ставшая уже стандартом де-факто для примеров база данных Northwind, для доступа к которой используется LINQ для SQL, подробно описанный в главе 3.
В примере мы будем работать с классом Customer, упрощенное представление которого приведено в листинге 5.5.
Листинг 5.5. Класс Customer
public class Customer {
public string CustomerlD {get; set;}
public string CompanyName {get; set;}
public string ContactName {get; set;}
public string ContactTitle {get; set;}
public string Address {get; set;}
public string City {get; set;}
public string Region {get; set;}
public string PostalCode {get; set;}
public string Country {get; set;}
public string Phone {get; set;}
public string Fax {get; set;}
public EntitySet<CustomerCustomerDemo>
CustomerCustomerDemos {get; set;}
public EntitySet<Order> Orders {get; set;}
}
Данные передаются контроллером HomeController представлению Index.aspx через коллекцию viewData в качестве перечислимой коллекции, возвращаемой вспомогательным методом-оберткой над стандартными классами, созданными LINQ для SQL. Код, отвечающий непосредственно за получение данных, не представляет интереса для целей этого примера и не приводится.
public ActionResult Index()
{
NorthwindDatabase db = new NorthwindDatabase();
ViewData["Message"] = "Список сотрудников";
ViewData["Customers"] =
db.GetCustomers(c => c.CompanyName, 5);
return View () ;
}
В результате представлению Index.aspx будет передана коллекция объектов типа Customer, которую требуется представить в виде таблицы. С использованием управляющего кода разметка представления может выглядеть так, как показано в листинге 5.6.
Листинг 5.6. Представление Index.aspx
<%@ Page Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage" %>
<%@ Import Namespace="MvcViewsDemo.Models" %>
<asp:Content ID="indexTitle"
ContentPlaceHolderID="TitleContent" runat="server">
Домашняя страница
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>
<%= Html.Encode(ViewData ["Message"]) %></h2>
<table>
<thead>
<tr>
<th>
Название компании
</th>
<th>
Контактное лицо
</th>
</tr>
</thead>
<% foreach
(Customer c in (IEnumerable<Customer>)ViewData["Customers"]
) { %>
<tr>
<td>
<%= c.CompanyName %>
</td>
<td>
<%= c.ContactName %>
</td>
</tr>
<% } %>
</table>
</asp:Content>
В результате выполнения примера приведенное ранее представление будет отображено в виде, показанном на рис. 5.1.
В тексте листинга 5.6 управляющие конструкции выделены полужирным шрифтом.
Как было отмечено ранее, при создании разметки представления могут быть использованы два типа управляющих конструкций, описанные далее.
<%= значение %>
Конструкция вида <%= значение %> используется для вывода значений в результирующий код HTML-разметки. Тип значения может быть любым, который может быть приведен к строке. Значение будет выведено именно в том месте разметки, в котором оно размещено.
<% управляющая конструкция %>
Управляющие инструкции позволяют проверять выполнение некоторых условий для вывода той или иной HTML-разметки (условия) либо многократно повторять фрагменты HTML-разметки (циклы).
Оформляются управляющие конструкции по приведенному далее шаблону.
<% инструкция (условия) { %>
Произвольный HTML-код, который может
перемежаться другими