Пока писалась эта книга, процесс разработки ASP.NET MVC Framework не стоял на месте. Сначала вышла предварительная версия ASP.NET MVC Preview 1, а затем и ASP.NET MVC Preview 2. Некоторое время спустя была выпущена и новая версия инструмента разработчиков Visual Studio 2010 Beta 2. На момент написания этой части книги Visual Studio 2010 Beta 2 и ASP.NET MVC Preview 2 — последние версии, доступные широкой аудитории разработчиков.
Новая вторая версия ASP.NET MVC принесла во Framework значительную порцию нового функционала, новых концепций, новых удобных инструментов и API. В этой части книги мы бы хотели кратко осветить то, что предлагается разработчиками ASP.NET в предварительных версиях Framework.
Области
Понятие областей (areas) для ASP.NET MVC — новая концепция. Суть областей сводится к тому, чтобы предоставить возможность разделить чрезмерно большой проект на несколько групп, которые продолжали бы взаимодействовать друг с другом. Например, в компании работает несколько групп разработчиков, которые создают большой проект, включающий в себя: основной сайт, магазин, обзоры товаров, форум, внутренний сайт по администрированию и пр. Для создания такого проекта ASP.NET MVC 2 предлагает выделить каждую отдельную часть проекта в область, вместе эти области продолжали бы представлять собой один взаимосвязанный проект. Выделение из большого проекта отдельных проектов-областей позволит разным группам разработчиков более независимо разрабатывать свои части приложения.
Предположим, что в крупной компании разрабатывается большой проект на базе ASP.NET MVC. Обычно группы, работающие над разными частями проекта, независимы друг от друга и связаны только спецификацией. Поэтому очень важно не допустить возможных конфликтов в программном коде, которые могут возникнуть, когда несколько частей большого проекта сливаются в одно целое. Так, например, группы, разрабатывающие части, отвечающие за магазин и за блог сайта, могут независимо друг от друга создать одноименные контроллеры AdminController. В случае, когда проект не основан на областях, слияние двух независимых частей с одноименным контроллером может быть сильно затруднено или невозможно. С использованием областей данная проблема решается, т. к. каждая область может иметь свой собственный независимый набор контроллеров.
Области предлагают механизм, схожий с пространствами имен в языках программирования. Они разделяют функционал частей и подсистем проекта на независимые составляющие, которые не могут конфликтовать друг с другом. Таким образом, области — это инструмент, помогающий разделять большой проект на малые независимые части для слаженной командной разработки.
Концепция областей появилась в ASP.NET MVC 2 Preview 1 в виде областей в решении с несколькими проектами. После выхода ASP.NET MVC 2 Preview 2 применение областей было расширено возможностью создавать области в одном проекте. Рассмотрим оба варианта.
Области для нескольких проектов
При создании решения с использованием областей, работающих для нескольких проектов, необходимо следовать следующим шагам:
1. Создать проект, который будет родительским (или главным) по отношению к проектам-областям.
2. Создать проекты-области, например, для форума, блога, магазина и т. д. В этих проектах требуется удалить файлы Global.asax, кроме того, можно удалить созданные по умолчанию файлы в папку Scripts, поскольку все скрипты будут браться из родительского проекта.
3. Добавить ссылки на проекты-области в родительском проекте.
4. Создать для каждого из проектов класс, наследующий от класса AreaRegistration, в котором перегрузить два элемента: метод RegisterArea и свойство AreaName. RegisterArea должен реализовать логику по регистрированию области в контексте приложения, свойство AreaName должно вернуть название области.
5. В родительском проекте в Global.asax необходимо вызвать метод AreaRegistration.RegisterAllAreas(); для регистрации областей в контексте приложения во время запуска.
6. Заключительным шагом, который требуется для успешного запуска проекта с областями, является модификация файлов проекта *.csproj (*.vbproj для проектов на Visual Basic) каждого из проектов. В каждого таком файле необходимо раскомментировать относящиеся к областям строки кода (будет показано далее).
Рассмотрим шаги немного подробнее. На рис. 9.1 показана структура решения, в котором содержится три проекта: родительский проект AreasProject и два проекта-области — Forum и Store, которые реализуют логику форума и магазина соответственно.
Рис. 9.1. Структура проекта ASP.NET MVC с областями
В проекте-области Forum создан контроллер ForumController, который реализует три действия: Index, AddPost, EditPost. Точно так же в проекте Store создан контроллер ProductsController с действиями List, AddReview и Details. Для отображения результатов действий созданы соответствующие представления. После создания проектов-областей в проект AreasProject были добавлены ссылки на эти проекты.
На рис. 9.1 вы можете заметить в проектах Store и Forum файл Routes.cs. Этот файл добавлен в проекты для того, чтобы реализовать класс AreaRegistration. Рассмотрим содержимое файла Routes.cs в проекте Store в листинге 9.1.
Листинг 9.1. Содержимое файла Routes.cs проекта Store
namespace Store
{
using System.Web.Mvc;
using System.Web.Routing;
public class Routes : AreaRegistration
{
public override void RegisterArea(
AreaRegistrationContext context)
{
context.MapRoute(
"Store_Default",
"Store/{controller}/{action}/{id}",
new {controller = "Products",
action = "List", id = ""},
new string[] { "Store.Controllers" }
);
}
public override string AreaName
{
get { return "Store"; }
}
}
}
Обратите внимание, класс Routes наследуется от AreaRegistration, что позволит подсистеме ASP.NET MVC в дальнейшем проинициализировать с помощью него подсистему областей. В классе Routes содержится два перегруженных члена: метод RegisterArea и свойство AreaName.
В RegisterArea производится регистрация маршрутов в контексте приложения с областями. С помощью context.MapRoute создается маршрут под названием store_Default. Последнее значение параметра new string[] { "Store.Controllers" } определяет пространство имен, в котором находятся контроллеры, сопоставленные данному маршруту.
Перегруженное свойство AreaName возвращает название области. Это имя в дальнейшем используется как ASP.NET MVC, так и разработчиком для указания области, из которой необходимо вызвать требуемый функционал.
Классы, подобные Routes для проекта Store, необходимо создать для каждого проекта в решении с областями.
Следующим шагом будет добавление в родительском проекте AreasProject в Global.asax следующей строки кода:
protected void Application_Start()
{
AreaReg±stration.Reg±sterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
Вызов AreaRegistration.RegisterAllAreas() при запуске приложения позволит ASP.NET MVC инициализировать все имеющиеся области и их маршруты в приложении.
Последним шагом, необходимым для запуска проекта с областями, является модификация файлов проекта *.csproj (или *.vbproj, если ваши проекты написаны на Visual Basic) для каждого из проектов в решении. Для того чтобы получить доступ к этим файлам, последовательно выгрузите проекты из решения с помощью команды UnloadProject. В контекстном меню на выгруженном проекте выберите Edit***.csproj (рис. 9.2), где *** — название проекта.
Рис. 9.2. Контекстное меню, позволяющее редактировать файл проекта
В файлах проектов содержится часть закомментированных определений, которые требуется раскомментировать для использования решения на базе областей. Для проектов-областей это куски кода с комментариями:
и
Для родительского проекта необходимо раскомментировать куски кода, помеченные:
и
Примечание
Возможно, что в следующих релизах ASP.NET MVC 2 действие с редактированием файлов проекта будет излишним. Ожидается, что работа с областями будет поддерживаться на уровне Solution Explorer, что облегчит создание новых областей и проектов на их базе.
*****************************
Теперь, когда проект подготовлен полностью, можно использовать проекты-области в родительском проекте следующим образом. Видоизменим в файл Site.Master в родительском проекте блок кода списка вкладок так, чтобы он выглядел, как во фрагменте:
Обратите внимание, что построение ссылок с помощью Html.ActionLink теперь требует указания области, в которой нужно найти контроллер и действие. Если мы запустим проект, то увидим следующее (рис. 9.3).
Новые вкладки Store и Forum будут работать согласно заданным правилам и отображать представления из проектов-областей.
Области в одном проекте
Если в решении предыдущего примера областей для нескольких проектов включить опцию показа скрытых файлов для родительского проекта, то мы увидим следующую картину (рис. 9.4).
В родительском проекте AreasProject в папке Views/Areas создаются скрытые элементы из проектов-областей. Это требуется для того, чтобы родительский проект самостоятельно отображал представления проектов-областей.
Однако эта структура скрытых файлов может быть использована и напрямую. В ASP.NET MVC 2 Preview 2 появилась возможность создания решений с одиночными проектами на базе областей. Такие решения содержат только один проект, в котором реализованы все области. На рис. 9.5 представлена структура одиночного проекта, где реализованы те же самые области, которые были реализованы в предыдущем разделе с помощью нескольких проектов-областей.
Чтобы создать такой проект, по аналогии с предыдущим примером, мы должны создать вместо нескольких проектов иерархию областей в одном проекте. Для этого в корне проекта необходимо создать папку Areas, в которой каждая созданная папка будет являться отдельной областью. На рис. 9.5 такими папками являются Forum и Store. В них следует создать папку Controllers и Views для контроллеров и представлений и реализовать их подобно тому, как мы сделали это в предыдущем разделе. Обратите внимание, что для каждой папки-области также нужно создать файл Routes.cs с реализацией класса AreaRegistration. Необходимо обновить и Global.asax, добавив в него вызов AreaRegistration.RegisterAllAreas ().
Приятное отличие разработки единичного проекта на базе областей от решения с несколькими проектами-областями состоит в том, что при создании одиночного проекта ASP.NET MVC на базе областей нет необходимости изменять его файл проекта, т. к. нет нужды обрабатывать зависимости между проектами. В целом, это несколько упрощает создание решения с областями.
Функционал областей — это полезный механизм, который позволяет разделить в большом решении логику различных частей на составные объекты — области. Вы можете выбрать, как области будут представлены в вашем решении: на базе нескольких проектов или же на базе только одного проекта. В любом случае, создание областей не составит труда и позволит вам удобно разделить разнородные функции в приложении.
Шаблонные помощники
Шаблонные помощники (templated helpers) — это новое средство в MVC 2, которое призвано сократить время разработки представлений. Шаблонные помощники строго типизированы и основаны на моделях приложения, кроме того, для вывода информации и валидации модели используется механизм DataAnnotations. В общем, шаблонных помощников можно представить себе как генератор разметки на базе определенной модели и правил, указанных с помощью атрибутов DataAnnotations.
Значительное преимущество шаблонных помощников состоит в том, что строгая типизация при их использовании позволяет еще на этапе написания кода и позже при компиляции избегать ошибок, связанных с неверными значениями параметров. Вместо указания параметров в виде текстовой строки, при написании которой можно допустить ошибки или опечатки, шаблонные помощники предлагают использовать элементы модели данных, что исключает подобные ошибки.
Для примера рассмотрим следующую модель данных:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Cost { get; set; }
public DateTime UpdatedAt { get; set; }
}
Класс Product представляет собой модель продукта для некого магазина. Модель содержит идентификатор, название, описание, стоимость и дату обновления.
Механизм шаблонных помощников устроен так, что позволяет отображать разметку для модели всего одной строчкой кода. Например, создадим контроллер StoreController и строготипизированное представление Info, основанное на Product, которое отображает информацию о продукте (листинг 9.2).
Листинг 9.2. Представление с использованием шаблонных помощников
<%@ Page Title="" Language="C#"
MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage
runat="server">
Информация о продукте
runat="server">
Info
<%= Html.DisplayFor(x => Model)%>
Обратите внимание на выделенный участок кода, который представляет собой одну строчку шаблонного помощника, предназначенную для вывода информации о переданном экземпляре модели.
Код контроллера StoreController для примера будет таким, как в листинге 9.3.
Листинг 9.3. Контроллер StoreController
namespace TemplatedHelpersProject.Controllers
{
using System;
using System.Web.Mvc;
using TemplatedHelpersProj ect.Models;
public class StoreController : Controller
{
public ActionResult Info()
{
var product = new Product() { Cost = 1,
Description = "Описание",
Id = 1, Name = "Товар",
UpdatedAt = DateTime.Now };
return View(product);
}
}
}
Запустим приложение на выполнение и перейдем на представление Store/Info. Результатом будет полная информация, заведенная нами в экземпляре Product (рис. 9.6).
Как вы можете увидеть, написав всего одну строчку кода в представлении, мы сформировали разметку для целой комплексной модели данных.
Шаблоны по умолчанию
Для работы с шаблонами по умолчанию ASP.NET MVC предлагает несколько стандартных методов расширения:
□ Html.LabelFor — производит рендеринг описательной информации для данных модели. По умолчанию выводит название поля модели;
□ Html.DisplayFor — производит рендеринг значений данных модели в соответствии с их типом;
□ Html.EditorFor — производит рендеринг элементов управления с данными модели для возможности редактирования.
Примечание
Кроме перечисленных стандартных методов расширения, в будущем планируется добавить методы: ValidationMessageFor, TextAreaFor, TextBoxFor, HiddenFor, DropDownListFor для соответствующей поддержки валидации и элементов управления в различных представлениях.
************************
Для всех этих методов расширения есть дополнительные методы LabelForModel, DisplayForModel и EditorForModel, которые являются сокращенным вариантом своих аналогов. Эти методы предназначены для рендеринга всей модели данных целиком без указания параметров.
Рассмотрим вариант рендеринга модели с помощью стандартных методов расширения. Для этого сформируем следующее представление (листинг 9.4).
Листинг 9.4. Модифицированное представление
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage
runat="server">
Info
runat="server">
Результат работы данного кода представлен на рис. 9.7.
Обратите внимание, что с использованием методов Html.LabelFor и Html.EditorFor для каждого элемента модели мы получили возможность осуществлять рендеринг данных в таком виде, в котором нам бы этого хотелось. Вместо стандартной разметки с использованием
- для представления только той ее части, которая нужна нам.
Создание шаблонов
Существует большая вероятность того, что один и тот же рендеринг одного и того же типа данных вам предстоит выполнить в разных представлениях. Для того чтобы поддержать такой сценарий, ASP.NET MVC предлагает разработчику создать один-единственный шаблон рендеринга типа данных, а затем использовать его во всех необходимых местах.
Для того чтобы создать шаблон представления типа данных, необходимо в папке нужного контроллера в папке представлений Views создать одну из папок: DisplayTemplates или EditorTemplates. DisplayTemplates должна содержать шаблоны для рендеринга представлений для просмотра, а EditorTemplates — для редактирования. Папки DisplayTemplates и EditorTemplates содержат частичные представления *.ascx, наименование которых соответствуют типам данных, с которыми необходимо работать.
Например, на рис. 9.8 в папке Views/Store представлена папка DisplayTemplates, которая содержит частичное представление Product.ascx. Это означает, что для рендеринга данных типа Product при работе в контроллере storeController будет использоваться шаблон Product.ascx.
Содержимое Product.ascx представлено в листинге 9.5.
Листинг 9.5. Содержимое Product.ascx
<%@ Control Language="C#"
Inherits="System.Web.Mvc.ViewUserControl
%>
Как вы можете убедиться, шаблон Product.ascx соответствует той разметке, которую мы создавали для рендеринга в листинге 9.4. Однако если теперь модифицировать код листинга 9.4 до простого варианта <%= Html.DisplayFor (x => Model) %>, то результат останется неизменным, т. к. механизм ASP.NET MVC, обнаружив имеющийся шаблон Product.ascx, использует его для рендеринга представления модели с типом Product.
Аннотация данных и валидация
ASP.NET MVC 2 имеет поддержку валидации данных на основании аннотации с помощью атрибутов из пространства имен System.ComponentModel.DataAnnotations.
Давайте улучшим наше представление, внеся изменение в модель так, как показано в листинге 9.6.
Листинг 9.6. Модель данных с аннотациями
namespace TemplatedHelpersProj ect.Models
{
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
public class Product
{
[DisplayName("Идентификатор")]
[HiddenInput]
public int Id { get; set; }
[DisplayName("Наименование товара")]
[Required(ErrorMessage = "Не указано наименование")]
public string Name { get; set; }
[DisplayName("Описание")] public string Description { get; set; }
[DisplayName("Цена")]
[Required(ErrorMessage="He указана цена")]
public decimal Cost { get; set; }
[DisplayName("Дата обновления")]
[HiddenInput(DisplayValue=false)]
public DateTime UpdatedAt { get; set; }
}
}
Обратите внимание на используемые атрибуты из пространства имен System.ComponentModel.DataAnnotations. С помощью этих атрибутов модель данных помечается метаданными, которые в дальнейшем автоматически используются в разных частях программы. Для демонстрации этого использования рассмотрим новое представление Edit для контроллера StoreController, предназначенное для редактирования данных (листинг 9.7).
Листинг 9.7. Представление для редактирования данных модели типа Product
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage
%>
runat="server">
Редактирование информации
runat="server">
Товар
<%= Html.ValidationSummary() %>
<% using(Html.BeginForm()) {%>
<%= Html.EditorFor(x => Model) %>
<%} %>
Обратите внимание, в представлении используется шаблонный помощник Html.EditorFor, назначение которого — формировать разметку для редактирования, соответствующую модели.
В контроллере storeController добавим действия Edit (листинг 9.8).
Листинг 9.8. Действия Edit
public ActionResult Edit()
{
var product = new Product() {
ost = 1,
Description = "Описание",
Id = 1,
Name = "Товар",
UpdatedAt = DateTime.Now };
return View(product);
}
[HttpPost]
public ActionResult Edit(Product product)
{
return View(product);
}
Теперь, запустив приложение на выполнение, перейдя на Store/Edit и пробуя обновить данные без указания некоторых полей, мы получим такую картину (рис. 9.9).
Обратите внимание на то, что подписи к полям и сообщения об ошибках валидации соответствуют тем данным, которые были заведены нами через атрибуты аннотации данных. Кроме того, с помощью атрибута Hiddeninput нам удалось скрыть данные о времени обновления и изменить представление поля идентификатора с редактируемого поля на обычное текстовое поле.
Этот пример показывает, как использование атрибутов DisplayName, Hiddeninput, Required и др. из пространства имен System.Component-Model.DataAnnotations позволяет создать для модели набор метаданных, которые позже используются ASP.NET MVC для формирования разметки, подписей к полям ввода и валидации и вывода информации об ошибках.
Кроме поддержки валидации на сервере, ASP.NET MVC 2 предлагает поддержку валидации и на клиенте с помощью библиотеки валидации, написанной для jQuery. Для автоматической валидации данных на стороне клиента по умолчанию поддерживаются следующие атрибуты аннотирования данных:
StringLengthAttribute, RequiredAttribute, RegexAttribute, RangeAttribute.
Для включения клиентской валидации необходимо добавить на страницу следующий код, подключить скрипты:
и для формы указать на необходимость использования клиентской валидации
<% using(Html.BeginForm()) { %>
//...
<% Html.EnableClientValidation(); %>
<% } %>
Кроме того, финальный вариант ASP.NET MVC 2 будет поддерживать новый механизм адаптеров, который позволит вам написать свой собственный провайдер клиентской валидации.
Классы метаданных
Существуют сценарии, когда аннотирование классов не представляется возможным, например, когда класс является автогенерируемым классом контекста данных Linq To Sql. Кроме того, вероятны сценарии, когда получение данных аннотации необходимо производить не с помощью атрибутов System.ComponentModel.DataAnnotations, а из других источников: базы данных или файлов XML.
Для поддержки таких сценариев в ASP.NET MVC введен механизм классов метаданных. Класс метаданных представляет собой обычный класс, служащий только для одной цели — предоставлять дополнительные данные — метаданные — о другом классе. Для примера добавим к нашему классу Product класс с метаданными, вынеся все данные аннотации в метакласс (листинг 9.9).
Листинг 9.9. Класс с метаданными для класса Product
namespace TemplatedHelpersProject.Models {
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
[MetadataType (typeof (ProductMetadata)) ]
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Cost { get; set; }
public DateTime UpdatedAt { get; set; }
}
public class ProductMetadata
{
[DisplayName("Идентификатор")]
[HiddenInput]
public int Id { get; set; }
[DisplayName("Наименование товара")]
[Required(ErrorMessage = "Не указано наименование")]
public string Name { get; set; }
[DisplayName("Описание")]
public string Description { get; set; }
[DisplayName("Цена")]
[Required(ErrorMessage="Не указана цена")]
public decimal Cost { get; set; }
[DisplayName("Дата обновления")]
[HiddenInput(DisplayValue=false)]
public DateTime UpdatedAt { get; set; }
}
}
Обратите внимание на выделенную строку [MetadataType(typeof (ProductMetadata))]. Атрибут MetadataType используется для того, чтобы показать механизму ASP.NET MVC, в каком классе следует искать метаданные. После выполнения кода мы убедимся, что перемещение метаданных из класса Product в класс ProductMetadata никак не отразилось на результате. Данные метаинформации стали потребляться из класса ProductMetadata, что и требовалось достичь.
Новые атрибуты
ASP.NET MVС 2 представляет набор новых атрибутов для разнообразных сфер применения. Далее вы найдете более полное описание.
Http***Attribute и перегрузка типов запросов
Ранее в ASP.NET MVC для ограничения выполнения действия в ответ на тип запроса применялся атрибут AcceptverbsAttribute с параметрами из перечисления HttpVerbs. В ASP.NET MVC 2 представлены альтернативные атрибуты для короткой записи: HttpPostAttribute, HttpPutAttribute, HttpGetAttribute, HttpDeleteAttribute.
Кроме атрибутов сокращенной формы, ASP.NET MVC 2 предлагает еще один механизм работы с запросами, который нацелен на REST-сценарии. При работе с REST-приложениями важной задачей ставится правильное оперирование типами запросов. Однако не все браузеры поддерживают типы запросов типа PUT или DELETE. Для преодоления этой проблемы в MVC 2 вводится новый метод расширения Html.HttpMethodOverride, который используется для перегрузки типа запроса, применяемого на форме. Например, в следующем коде формируется POST-форма (по умолчанию) с перегрузкой параметра запроса в PUT с помощью Html.HttpMethodOverride:
<% using(Html.BeginForm()) {%>
<%= Html.HttpMethodDverride(HttpVerbs.Put) %>
<%} %>
Этот механизм работает следующим образом: вызов Html.HttpMethodOverride формирует на форме следующее скрытое поле:
При получении запроса с формы ASP.NET MVC ищет скрытое поле со значением X-HTTP-Method-Override и, если оно найдено, предполагает, что запрос представляет собой тип, указанный в скрытом поле. Таким образом, указанный ранее пример вызовет действие, помеченное атрибутом HttpPut, но не HttpPost, т. к. форма содержит перегруженный тип запроса. Перегрузка значения может выполняться не только с помощью скрытого поля, но и с помощью заголовков HTTP или параметров строки запроса.
Следует учесть, что перегрузка запросов возможна только для POST-запросов. Во всех других случаях скрытый параметр X-HTTP-Method-Override игнорируется.
DefauItValueAttribute
С помощью атрибута System.ComponentModel.DefaultValueAttribute в MVC 2 становится возможным указывать значения по умолчанию для параметров действий.
public class ArticleController
{
public ActionResult View(int id, [DefaultValue(1)]int page)
{
}
}
В приведенном ранее примере для параметра page определяется значение по умолчанию, которое следует использовать в случаях, когда запрос не содержал явного указания значения для данного параметра. Эта задача может быть решена для всех действий сразу через создание параметров маршрутизации по умолчанию. Но в случаях, когда требуется создать разные значения по умолчанию для разных действий, может быть использован атрибут DefaultValue.
RequireHttpsAttribute
Новый атрибут RequireHttpsAttribute в MVC 2 позволит вам пометить действия, вызов которых должен быть произведен только по защищенному протоколу HTTPS.
Улучшения в связывании данных
ASP.NET MVC 2 предоставит новую возможность по связыванию данных. Теперь в MVC 2 связывание данных возможно и с бинарными типами данных, представленными byte[] и System.Data.Linq.Binary. Для этих целей введены два новых перегруженных метода расширения Hidden:
public static string Hidden(this HtmlHelper htmlHelper, string name, Binary value);
public static string Hidden(this HtmlHelper htmlHelper, string name, byte[] value);
После использования этих методов для бинарных данных в разметке будет произведен рендеринг скрытого элемента hidden со строкой данных, закодированной по base-64. После отправки запроса с формы, которая содержит данный скрытый элемент, его данные будут декодированы и связаны с соответствующим значением модели.
Прочие улучшения в API
Кроме перечисленных ранее значительных нововведений, ASP.NET MVC 2 предложит еще ряд менее значительных изменений в API:
□ новый защищенный виртуальный метод createActioninvoker в классе controller, который вызывается свойством Actioninvoker и позволяет создавать отложенное создание экземпляра (instantiation) инициатора, если он не установлен;
□ новый защищенный виртуальный метод OnAuthorizationFailed в классе AuthorizationFilter, который позволяет фильтрам авторизации отрабатывать ситуации, когда авторизация была провалена;
□ новый метод Add(stringkey, object value) у класса ValueProviderDictionary, который позволяет проще задавать значения для экземпляров класса;
□ новое свойство ActionDescriptor в классе AuthorizationContext;
□ метод Controller.Execute теперь вызовет исключение в ситуации, когда он вызван более одного раза в одном экземпляре. Это означает явное ограничение на вызов единственного экземпляра контроллера на каждый запрос;
□ класс Controller более не наследуется от MarshalByRefObject;
□ конструктор AuthorizationContext(ControllerContext context) объявлен устаревшим, вместо него предлагается использовать вариант с двумя параметрами;
□ внесены изменения в типы моделей так, что они теперь могут быть не только ссылочными типами, но и значениями. Например, в MVC 2 можно будет использовать System.Int32 как тип модели;
□ поиск контроллеров в пространстве имен, указанном при регистрации маршрутов, теперь будет выполняться и в подпространствах имен.
Кроме нововведений, MVC 2 содержит изменения, которые "ломают" совместимость с существующим кодом:
□ из класса DefaultControllerFactory исключено свойство RequestContext, вместо этого значение RequestContext передается в методы GetControllerinstance и GetControllerType. Это изменение нарушает работу пользовательских вариантов фабрики контроллеров, которые наследовались от класса DefaultControllerFactory;
□ строковое значение area в MVC 2 стало зарезервированным значением, которое нельзя использовать в качестве параметров маршрута при создании маршрутизации. В этом area стало похоже на бывшие ранее зарегистрированными строки controller и action;
□ методы расширения хелпер-классов (вспомогательных классов) отныне возвращают MvcHtmlString, вместо строки. Это нововведение рассчитано на использование в окружении ASP.NET 4.0 для получения преимуществ от нового синтаксиса элементов HTML-кодирования;
□ действия, которые возвращают JsonResult, в MVC 2 обязаны вызываться только в ответ на POST-запросы, это ограничение введено в целях повышения безопасности, поскольку обнаружены новые типы атак JSON Hijacking, осуществляемые при GET-запросах JSON-данных. Однако MVC 2 будет поддерживать способ обойти это ограничение через использование свойства JsonRequestBehavior у класса JsonResult;
□ свойства Model и ModelType объявлены устаревшими, вместо них предлагается использовать новое свойство ModelMetadata, которое содержит в себе данные Model и ModelType.
Нововведения Visual Studio 2010
Релиз Visual Studio 2010 будет содержать финальную версию ASP.NET MVC 2. Для более полной поддержки работы с MVC в Visual Studio 2008 и 2010 будут внесены некоторые изменения: введена поддержка создания областей с помощью элементов интерфейса и помощников, добавлены сниппеты (snippet — фрагмент) для быстрого создания кусочков кода.
Кроме того, MVC 2 будет содержать новый тип проекта, который будет представлять собой облегченный, "пустой" вариант текущего проекта MVC. В нем будут отсутствовать готовые контроллеры AccountController, HomeController и не будет готовых представлений или элементов страниц MasterPage.
Visual Studio 2010 получит новый профиль среды разработки под названием Web Development (Code Optimized). Профиль среды разработки определяет набор инструментов и внешний вид Visual Studio. Профиль Code Optimized оптимизирован для более удобного набора кода и увеличения рабочего пространства за счет сокрытия панелей с кнопками и элементами управления.
Далее приведены еще некоторые полезные нововведения в Visual Studio 2010, которые могут быть полезны при разработке проектов на ASP.NET MVC.
Мультитаргетинг в Visual Studio 2010
В Visual Studio 2010 понятие мультитаргетинга, т. е. поддержка сразу нескольких версий платформы .NET, приобретает новые возможности. Так как .NET 4.0 Framework содержит новую версию исполняемой среды CLR 4.0, то при установке Framework не заменит собой .NET 3.5, но предложит двум версиям существовать одновременно. Теперь, в зависимости от выбранной версии Framework (рис. 9.10), IntelliSense в Visual Studio будет отображать именно характерные для номера Framework имена методов, свойств, полей и т. д.
Поддержка нескольких мониторов
Для удобства разработчиков, которые используют в своей работе несколько мониторов (от двух и более), Visual Studio 2010 содержит ряд нововведений, которые помогут в полной мере задействовать мониторы в работе.
В связи с тем, что все окна в Visual Studio 2008 были частью одного главного окна, пользователи не имели возможности вынести часть окон на другие мониторы. В Visual Studio 2010 это проблема решена, теперь разработчик может расположить любые панели инструментов, информационные окна, окна редакторов кода и другие на разных мониторах (рис. 9.11).
Сниппеты JavaScript, Html, ASP.NET в Visual Studio 2010
Сниппет — это полезный инструмент, который позволяет сократить время, затрачиваемое разработчиком на набор кода. Сниппет представляет собой короткую команду, которая разворачивается в некий шаблон кода. Например, сниппет foreach для C# разворачивается в одноименный шаблон создания цикла foreach. Для того чтобы использовать сниппет, необходимо набрать его и нажать клавишу
Visual Studio 2010 вводит поддержку сниппетов для быстрого набора HTML-, ASP.NET- и JavaScript-кода (рис. 9.12). Использование сниппетов позволит значительно ускорить рутинный набор кода для ASP.NET-страниц и элементов управления или скриптов JavaScript.
Что дальше?
Кроме перечисленных ранее функций, которые появились в MV C 2 Preview 2, планируется, что финальный вариант ASP.NET MVC 2 будет содержать еще ряд нововведений:
□ методы расширения Html.RenderAction и Html.Action, которые ранее являлись частью библиотеки MVC Futures, станут частью MVC 2. Эти методы предназначены для формирования разметки на основе результата действия и внедрении ее в определенное представление. Таким образом, в представлении можно будет выводить результат действий из других контроллеров;
□ будет расширен набор строготипизированных вспомогательных методов расширения для работы с шаблонами, добавятся методы: ValidationMessageFor, TextAreaFor, TextBoxFor, HiddenFor, DropDownListFor;
□ изменится поведение TempDataDictionary. Ее значения будут удаляться не после второго запроса, а сразу после чтения, что означает, что если данные TempData были прочтены в контексте этого же запроса, то они не будут доступны в следующем, как это могло бы быть в первой версии MVC. Данные в TempData будут сохранены даже после второго запроса, если их не прочитали. Для сохранения данных и после чтения будет предоставлен метод Keep, который позволит продлить жизнь данных в TempData;
□ асинхронные контроллеры, представленные в библиотеке MVC Futures, будут включены в финальный вариант ASP.NET MVC 2;
□ появится возможность создавать и использовать несколько провайдеров валидации, серверной и клиентской;
□ появится возможность перегружать создание TempDataProvider с помощью нового метода CreateTempDataProvider в классе Controller.
Заключение
ASP.NET MVC развивается значительными темпами, что показал период времени, за который была написана эта книга. За это время вышло несколько версий ASP.NET MVC 2, каждая из которых привнесла новый богатый функционал и изменила к лучшему старый.
ASP.NET MVC— это молодой, но мощный Framework, и если его развитие продолжится теми же темпами, которыми он развивается сейчас, то вскоре ASP.NET MVC станет мощнейшим инструментом разработки веб-сайтов, включающим в себя как средства для создания чистого быстрого кода для небольших проектов, так и средства, востребованные в корпоративной среде. Кроме того, поддержка Ajax, асинхронного выполнения, областей и улучшенная безопасность — это то, чего стоит ждать в финальной версии MVC 2 — следующей версии Framework.
Остается только пожелать инструменту ASP.NET MVC и дальше получать новые средства, новые инструменты и функционал, который будет востребован специалистами веб-разработки самого широкого профиля. Пусть ASP.NET MVC обретает все большую заслуженную популярность.