Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
CheckBootSpeed - это диагностический пакет на основе скриптов PowerShell, создающий отчет о скорости загрузки Windows 7 ...
Вы когда-нибудь хотели создать установочный диск Windows, который бы автоматически установил систему, не задавая вопросо...
Если после установки Windows XP у вас перестала загружаться Windows Vista или Windows 7, вам необходимо восстановить заг...
Программа подготовки документов и ведения учетных и отчетных данных по командировкам. Используются формы, утвержденные п...
Red Button – это мощная утилита для оптимизации и очистки всех актуальных клиентских версий операционной системы Windows...
OSzone.net Microsoft Разработка приложений .NET Framework Перенос ASP.NET Web Forms в шаблон MVC с помощью ASP.NET Web API RSS

Перенос ASP.NET Web Forms в шаблон MVC с помощью ASP.NET Web API

Текущий рейтинг: 4.75 (проголосовало 4)
 Посетителей: 1841 | Просмотров: 3422 (сегодня 0)  Шрифт: - +

Хотя в наши дни ASP.NET MVC привлекает наибольшее внимание, ASP.NET Web Forms и связанные с ней элементы управления позволяют разработчикам создавать мощные интерактивные UI в короткие сроки — вот почему так много приложений ASP.NET Web Forms. Но вот что ASP.NET Web Forms не поддерживает, так это реализацию шаблонов Model-View-Controller (MVC) и Model-View-ViewModel (MVVM), обеспечивающих разработку, управляемую тестами (test-driven development, TDD).

ASP.NET Web API (далее — Web API) позволяет создавать или выполнять рефакторинг приложений ASP.NET Web Forms для шаблона MVC, перемещая код из файла отделенного кода в контроллер Web API. Этот процесс также позволяет приложениям ASP.NET использовать Asynchronous JavaScript and XML (AJAX), с помощью которого можно создавать более «отзывчивый» UI и повышать масштабируемость приложения за счет переноса логики в клиент и уменьшения интенсивности взаимодействия с сервером. Это возможно благодаря тому, что Web API использует протокол HTTP и (по соглашению кодирования) автоматически берет на себя несколько низкоуровневых задач. Парадигма Web API для ASP.NET, которая предлагается в этой статье, — дать возможность ASP.NET генерировать начальный набор разметки, посылаемой браузеру, но обрабатывать все взаимодействие с пользователем через AJAX-вызовы, адресованные автономному, тестируемому контроллеру.

Web API использует протокол HTTP и (по соглашению кодирования) автоматически берет на себя несколько низкоуровневых задач.

Подготовка инфраструктуры для того, чтобы приложение Web Forms взаимодействовало с сервером через набор AJAX-вызовов, не столь трудна. Но не стану вводить вас в заблуждение: рефакторинг кода в файле отделенного кода приложении Web Forms для работы с контроллером Web API может оказаться далеко не тривиальной задачей. Вам придется отказаться от различных событий, генерируемых элементами управления, автоматически генерируемой проверки на серверной стороне и от ViewState. Однако, как вы увидите, существуют некоторые обходные пути, позволяющие обойтись без этих средств, а это может ослабить головную боль, связанную с рефакторингом кода.

Добавление инфраструктуры Web API

Чтобы задействовать Web API в проекте ASP.NET, нужно лишь (после добавления NuGet-пакета Microsoft ASP.NET Web API) щелкнуть правой кнопкой мыши и выбрать Add | New Item | Web API Controller Class. Однако добавление контроллера таким способом приводит к созданию класса с большим объемом кода по умолчанию, который вам придется просто удалить. Возможно, вы предпочтете добавить обычный файл класса и унаследовать его от класса System.Web.Http.ApiController. Чтобы работать с инфраструктурой диспетчеризации ASP.NET, имя вашего класса должно заканчиваться строкой «Controller».

Класс контроллера Web API поддерживает большую часть кодирования по соглашению.

В этом примере создается контроллер Web API с именем Customer:

public class CustomerController : ApiController
{

Класс контроллера Web API поддерживает большую часть кодирования по соглашению. Например, чтобы при каждой обратной передаче формы на сервер вызывался некий метод, вам нужно лишь назвать этот метод «Post» или присвоить ему имя, которое начинается с «Post» (на внутреннем уровне страница, передаваемая обратно на сервер, посылается ему HTTP-командой POST; Web API выбирает методы на основе HTTP-команды запроса). Если такое имя метода нарушает соглашение по кодированию в вашей организации, вы можете использовать атрибут HttpPost, чтобы пометить метод, применяемый при обратной передаче данных на сервер. Следующий код создает метод с именем UpdateCustomer в контроллере Customer для обработки HTTP-передач:

public class CustomerController : ApiController
{
  [HttpPost]
  public void UpdateCustomer()
  {

Post-методы принимают максимум один параметр (post-методы с несколькими параметрами игнорируются). Простейшие данные, которые можно отправить в post-метод, — единственное значение в теле post, которому предшествует префикс — знак равенства (например, «=ALFKI»). Web API будет автоматически сопоставлять эти данные с единственным параметром post-метода — при условии, что данный параметр дополнен атрибутом FromBody, как в этом примере:

[HttpPost]
public HttpResponseMessage UpdateCustomer([FromBody] string CustID)
{

Конечно, это практически бесполезно. Если вам нужно передать обратно на сервер более одного значения, например данные веб-формы, то вам потребуется определить класс, который будет хранить значения из этой веб-формы: Data Transfer Object (DTO). Здесь помогают стандарты соглашений по кодированию в Web API. Вам нужно лишь определить класс с именами свойств, совпадающими с именами, которые присвоены элементам управления в веб-форме, и тогда ваши DTO-свойства будут автоматически заполняться данными из веб-формы с помощью Web API.

В качестве примера данных, которые можно отправить обратно контроллеру Web API, взгляните на веб-форму (согласитесь, что она очень проста) на рис. 1, где присутствуют всего три TextBox, RequiredFieldValidator и Button.

Рис. 1. Базовый пример веб-формы

<form id="form1" runat="server">
<p>
  Company Id: <asp:TextBox ID="CustomerID"
    ClientIDMode="Static" runat="server">
    </asp:TextBox> <br/>
  Company Name: <asp:TextBox ID="CompanyName"
    ClientIDMode="Static" runat="server">
    </asp:TextBox>
  <asp:RequiredFieldValidator ID="RequiredFieldValidator1"
    runat="server" ControlToValidate="CompanyName"
    Display="Dynamic"
    ErrorMessage="Company Name must be provided">
  </asp:RequiredFieldValidator><br/>
  City: <asp:TextBox ID="City"
    ClientIDMode="Static" runat="server"> 
    </asp:TextBox><br/>
</p>
<p>
  <asp:Button ID="PostButton" runat="server" Text="Update" />
</p>
</form>

Чтобы post-метод принимал данные от текстовых полей в этой веб-форме, вам пришлось бы создать класс со свойствами, имена которых совпадают с свойствами ID элементов управления TextBox, как сделано ниже (любые элементы управления в веб-форме, не имеющие совпадающего по имени свойства, игнорируются Web API):

public class CustomerDTO
{
  public string CustomerID { get; set; }
  public string CompanyName { get; set; }
  public string City { get; set; }
}

Более сложная веб-форма может потребовать такого DTO, с которым вы не уживетесь (или он выйдет за рамки возможностей Web API в связывании с данными). В этом случае вы можете создать свой Model Binder для сопоставления данных от элементов управления веб-формы со свойствами DTO. В сценарии с рефакторингом код в вашей веб-форме уже будет работать с именами элементов управления ASP.NET — наличие идентично именованных свойств в DTO уменьшит объемы работ, необходимых для переноса этого кода в контроллер Web API.

Диспетчеризация веб-формы

Следующий шаг в интеграции Web API в ASPX-цикл обработки веб-формы — предоставление правила диспетчеризации (routing rule) в событии Application_Start файла Global.asax приложения, которое будет направлять обратную передачу формы вашему контроллеру. Это правило состоит из шаблона, указывающего URL-адреса, к которым применяется данное правило, и какой контроллер должен обрабатывать запрос. Шаблон также задает, где в URL следует искать значения, которые должны использоваться Web API (включая значения, передаваемые методам в контроллере).

Здесь некоторые стандартные практики можно игнорировать. Стандартному правилу диспетчеризации может соответствовать почти любой URL, что может привести к неожиданным результатам, когда это правило применяется к URL, которые вы не собирались использовать. Чтобы избежать этого, Microsoft рекомендует начинать URL, сопоставляемые с Web API, со строки «api»; это предотвращает конфликты с URL, используемыми в других частях приложения. Этот маркер «api» не выполняет никаких полезных функция, а просто дополняет требуемые URL.

Сведя все это воедино, вы в конечном счете получите универсальное правило диспетчеризации в событии Application_Start, которое будет выглядеть, как показано ниже (для поддержки этого кода вам понадобится добавить в Global.asax выражения using для System.Web.Routing и System.Web.Http):

RouteTable.Routes.MapHttpRoute(
  "API Default",
  "api/{controller}/{id}",
  new { id = RouteParameter.Optional })
);

Это приводит к извлечению имени контроллера из второго параметра в шаблоне, и URL становятся жестко связанными с контроллерами. Если вы переименуете контроллер, любые клиенты, использующие этот URL, прекратят работать. (Я также предпочитаю, чтобы любые параметры, помещаемые в URL шаблоном, имели более осмысленные имена, чем просто «id».) Я стал предпочитать более специфичные правила диспетчеризации, не требующие задания имени контроллера в шаблоне, а вместо этого указывающие имя контроллера в значениях по умолчанию, передаваемых в третьем параметре методу MapHttpRoute. Сделав шаблоны в своих правилах диспетчеризации более специфичными, я вдобавок избегаю необходимости в специальном префиксе для URL, используемых с контроллерами Web API, и гораздо реже удивляюсь результатам, получаемым при использовании своих правил диспетчеризации.

Мои правила диспетчеризации выглядят примерно как следующий код, который создает маршрут под названием CustomerManagementPost, применяемый только к URL, начинающимся с «CustomerManagement» (за которым следуют имена сервера и сайта):

RouteTable.Routes.MapHttpRoute(
  "CustomerManagementPost",
  "CustomerManagement",
  new { Controller = "Customer" },
  new { httpMethod = new HttpMethodConstraint("Post") }
);

Это правило можно было применять, например, только к URL вроде www.phivs.com/CustomerManagement. В значениях по умолчанию я связываю этот URL с контроллером Customer. Просто чтобы убедиться, что этот маршрут используется, только когда мне это нужно, я применяю четвертый параметр, указывая, что этот маршрут используется лишь при обратной передаче данных как HTTP POST.

Первый шаг в исключении цикла «запрос-ответ» — вставка в процесс кое-какого кода на JavaScript.

Рефакторинг веб-формы для контроллера

Если вы занимаетесь рефакторингом существующей веб-формы, то следующий шаг — заставить эту веб-форму отправлять свои данные по новому, только что определенному маршруту, а не самой себе. Это первое изменение в существующем коде — все остальное, что было сделано до сих пор, заставляло добавлять код, оставляя существующую обработку на месте. Пересмотренный тег form должен выглядеть так:

<form id="form1" runat="server" action="CustomerManagement"
   method="post" enctype="application/x-www-form-urlencoded">

Здесь ключевое изменение — настройка атрибута action тега form на использование URL, указанного в маршруте («CustomerManagement»). Атрибуты method и enctype помогают обеспечить совместимость между браузерами. Когда происходит обратная передача страницы контроллеру, Web API будет автоматически вызывать post-метод, создавать экземпляр класса, передаваемого методу, и сопоставлять данные от веб-формы со свойствами в DTO, а затем передавать DTO в post-метод.

Собрав все воедино, вы теперь можете написать код в post-методе контроллера для работы с данными в DTO. Следующий код обновляет совпадающий объект сущности Entity Framework для модели, основанной на базе данных Northwind, и использует данные, переданные с веб-формы:

[HttpPost]
public void UpdateCustomer(CustomerDTO custDTO)
{
  Northwind ne = new Northwind();
  Customer cust = (from c in ne.Customers
                   where c.CustomerID == custDTO.CustomerID
                   select c).SingleOrDefault();
  if (cust != null)
  {
    cust.CompanyName = custDTO.CompanyName;
  }
  ne.SaveChanges();

Когда обработка завершается, клиенту нужно что-то вернуть. Изначально я буду просто возвращать объект HttpResponseMessage, сконфигурированный на перенаправление пользователя на другую ASPX-страницу сайта (рефакторинг впоследствии поможет улучшить эту процедуру). Мне нужно модифицировать post-метод для возврата HttpResponseMessage:

[HttpPost]
public HttpResponseMessage UpdateCustomer(CustomerDTO custDTO)

Затем добавить код в конец метода, который возвращает ответ перенаправления клиенту:

HttpResponseMessage rsp = new HttpResponseMessage();
  rsp.StatusCode = HttpStatusCode.Redirect;
  rsp.Headers.Location = new Uri("RecordSaved.aspx", UriKind.Relative);
  return rsp;
}

Теперь начинается реальная работа, в том числе:

  • перемещение любого кода, который был в ASPX-файле кода, в новый метод контроллера;
  • добавление любых проверок на серверной стороне, выполняемых элементами управления Validation;
  • отделение кода от событий, генерируемых страницей.

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

К этому моменту в рефакторинге существующей веб-формы вы перешли на шаблон MVC, но еще не взяли на вооружение парадигму AJAX. Страница по-прежнему использует традиционный цикл запроса-ответа вместо того, чтобы исключить обратные передачи страницы. Следующий шаг — создать страницу с настоящей поддержкой AJAX.

Переход на AJAX

Первый шаг в исключении цикла «запрос-ответ» — вставка в процесс кое-какого кода на JavaScript с настройкой свойства OnClientClick кнопки на вызов клиентской функции. Вот пример, где кнопка вызывает JavaScript-функцию UpdateCustomer:

<asp:Button ID="PostButton" runat="server" Text="Update"
  OnClientClick="return UpdateCustomer();" />

В этой функции вы перехватываете обратную передачу, инициированную щелчком кнопки, и заменяете ее AJAX-вызовом методом своего сервиса. Используя ключевое слово return в OnClientClick и заставляя UpdateCustomer вернуть false, вы подавляете обратную передачу, инициированную этой кнопкой. Ваша функция перехвата должны также вызывать любой код проверки на клиентской стороне, генерируемый элементами управления ASP.NET Validation, вызовом предоставляемой ASP.NET функции Page_ClientValidate (в процессе рефакторинга вызов кода проверки на клиентской стороне позволит вам избежать воссоздания элементов управления проверки на серверной стороне).

Если вы выполняете рефакторинг существующей веб-формы, то теперь можете удалить атрибут action в теге form, который использует ваш маршрут. Удаление этого атрибута позволяет реализовать гибридных/поэтапный подход к перемещению кода вашей веб-формы в контроллер Web API. В коде, который вы пока не хотите перемещать в контроллер, можно по-прежнему разрешать веб-форме выполнять обратную передачу самой себе. Например, в функции перехвата вы можете проверять, какие изменения произошли в веб-форме, и возвращать true из функции перехвата, чтобы дать продолжить обратную передачу. Если на странице несколько элементов управления, инициирующих обратные передачи, вы можете выбрать, какие элементы управления обрабатывать в контроллере Web API и написать функцию перехвата только для них. Это позволяет реализовать гибридный подход при рефакторинге (оставив часть кода в веб-форме) или поэтапный подход (постепенный перенос кода).

Теперь UpdateMethod должен вызвать сервис Web API, в который ранее происходила обратная передача страницы. Добавление jQuery к проекту и странице (я использовал jQuery 1.8.3) позволяет использовать его post-функцию для вызова вашего сервиса Web API. jQuery-функция serialize преобразует форму в набор пар «имя-значение», которые Web API сопоставит с именами свойств в объекте CustomerDTO. Интеграция этого вызова в функцию UpdateCustomer (так чтобы передача происходила только в отсутствие ошибок на клиентской стороне) дает такой код:

function UpdateCustomer() {
  if (Page_ClientValidate()){
    $.post('CustomerManagement', $('#form1').serialize())
    .success(function () {
      // Что-то делаем, чтобы сообщить пользователю о том,
      // что все прошло успешно
    })
    .error(function (data, msg, detail) {
      alert(data + '\n' + msg + '\n' + detail)
    });
  }
  return false;
}

При сериализации формы контроллеру пересылается много данных, не все из которых могут понадобиться (например, ViewState). Немного позже я покажу, как отправлять только необходимые данные.

Заключительный шаг (по крайней мере в этом простом примере) — переписывание конца post-метода в контроллере, так чтобы пользователь оставался на текущей странице. Эта версия post-метода просто возвращает HTTP-состояние OK, используя класс HttpResponseMessage:

...
  ne.SaveChanges();
  HttpResponseMessage rsp = new HttpResponseMessage();
  rsp.StatusCode = HttpStatusCode.OK;
  return rsp;
}

Обработка в рабочем процессе

Теперь вы должны решить, куда вы передадите задачу дальнейшей обработки. Как показано ранее, если пользователь должен переходить на другую страницу, это можно обрабатывать в контроллере. Однако, если контроллер теперь просто возвращает клиенту сообщение OK, дополнительную обработку желательно выполнять на клиенте. Например, неплохо начать с добавления метки к веб-форме для отображения результата обработки на серверной стороне:

Update Status: <asp:Label ID="Messages" runat="server" Text=""></asp:Label>

В методе success вашего AJAX-вызова вы могли бы обновлять метку состоянием AJAX-вызова:

success: function (data, status) {
  $("#Messages").text(status); 
},

Для серверного кода веб-формы нет ничего необычного в том, что в процессе обработки переданной страницы он обновляет элементы управления на странице перед ее возвратом пользователю. Для обработки этого вам понадобится возвращать данные от post-метода сервиса и обновлять страницу из вашей JavaScript-функции.

Первый этап в этом процессе — настройка свойства Content объекта HttpResponseMessage на хранение возвращаемых вами данных. Поскольку DTO для передачи данных post-методу от формы уже есть, то имеет смысл использовать его для отправки данных обратно клиенту. Однако для использования с Web API нет нужды помечать ваш класс DTO атрибутом Serializable. (По сути, если вы все же пометите DTO этим атрибутом, поддерживающие поля для свойств DTO будут сериализоваться и посылаться клиенту, из-за чего вам придется иметь дело со странными именами в клиентской версии DTO.)

Следующий код обновляет DTO-свойство City и перемещает его содержимое в свойство Content объекта HttpResponseMessage, отформатированное в виде JSON-объекта (вам потребуется добавить выражение using для System.Net.Http.Headers в контроллер, чтобы этот код работал):

HttpResponseMessage rsp = new HttpResponseMessage();
rsp.StatusCode = HttpStatusCode.OK;
custDTO.City = cust.City;
rsp.Content = new ObjectContent<CustomerDTO>(custDTO,
              new JsonMediaTypeFormatter(),
              new MediaTypeWithQualityHeaderValue("application/json"));

Последний этап — улучшение функции перехвата, чтобы ее метод success перемещал данные в форму:

.success(function (data, status) {
  $("#Messages").text(status);
  if (status == "success") {
    $("#City").val(data.City);
  }
})

Этот код, конечно, не обновляет ASP.NET ViewState. Если страница потом подвергается обратной передаче в обычном стиле ASP.NET, то City TextBox вызовет событие TextChanged. Если в веб-форме есть серверный код, связанный с этим событием, все может закончиться неприятностями. Вам надо заранее проверить это, если вы используете поэтапную миграцию или гибридный подход. В полностью реализованной версии парадигмы, где веб-форма не передается обратно на сервер после изначального отображения, это не является проблемой.

Замена событий

Как я уже говорил, вам придется обходиться без серверных событий ASP.NET. Однако вы можете вместо этого захватывать эквивалентные JavaScript-события, которые инициируют обратную передачу на сервер и вызывают метод в вашем сервисе, делающий то, что делал бы код в обработчике события на серверной стороне. Это используется в поэтапном процессе рефакторинга, позволяя переносить такие события по мере того, как вы к этому готовы.

Большинство ASP.NET-страниц не проектировалось с учетом HTTP-команд.

Например, если на странице есть кнопка Delete для удаления текущего показываемого Customer, вы можете оставить эту функциональность в файле кода страницы на этапе начальной миграции — просто позвольте кнопке Delete выполнять обратную передачу страницы на сервер. Когда вы готовы к переносу функции удаления, начните с добавления функции для перехвата клиентского события onclick кнопки Delete. В этом примере я предпочел подключить событие в JavaScript — такая тактика будет работать с любым событием на клиентской стороне:

<asp:Button ID="DeleteButton" runat="server" Text="Delete"  />
<script type="text/javascript">
  $(function () {
    $("#DeleteButton").click(function () { return DeleteCustomer() });
  })

В функции DeleteCustomer вместо сериализации всей страницы я буду отправлять только те данные, которые нужны методу delete на серверной стороне: CustomerID. Поскольку я могу встроить этот единственный параметр в URL, используемый для запроса сервиса, это позволяет мне задействовать другую стандартную HTTP-команду для выбора правильного метода контроллера: DELETE (подробнее о HTTP-командах см. по ссылке bit.ly/92iEnV).

Рефакторинг файла кода для традиционной ASPX-страницы с целью переноса его кода в контроллер Web API — задача далеко не тривиальная.

Используя jQuery-функцию ajax, я могу выдать запрос своему контроллеру, сформировать URL с данными от страницы и указать, что HTTP-команду DELETE следует использовать как тип запроса (рис. 2).

Рис. 2. Применение jQuery-функциональности AJAX для выдачи запроса контроллеру

function DeleteCustomer() {               
  $.ajax({
    url: 'CustomerManagement/' + $("#CustomerID").val(),
    type: 'delete',
    success: function (data, status) {
      $("#Messages").text(status);                       
  },
  error: function (data, msg, detail) {
    alert(data + '\n' + msg + '\n' + detail)
    }
  });
  return false;
}

Следующий шаг — создание правила диспетчеризации, которое будет идентифицировать, какая часть URL содержит CustomerID, и присваивать это значение какому-либо параметру (в данном случае — параметру CustID):

RouteTable.Routes.MapHttpRoute(
  "CustomerManagementDelete",
  "CustomerManagement/{CustID}",
  new { Controller = "Customer" },
  new { httpMethod = new HttpMethodConstraint("Delete") }
);

Как и при использовании post-метода, Web API будет автоматически направлять HTTP-запрос DELETE одноименному методу (или с именем, начинающимся с «Delete») в контроллере или методу, помеченному атрибутом HttpDelete. Как и раньше, Web API будет автоматически сопоставлять любые данные, извлеченные из URL, параметрам метода, имя которого совпадает с именем в шаблоне:

[HttpDelete]
public HttpResponseMessage FlagCustomerAsDeleted(string CustID)
{
  //...код, обновляющий объект Customer...
  HttpResponseMessage rsp = new HttpResponseMessage();
  rsp.StatusCode = HttpStatusCode.OK;
  return rsp;
}

За рамками HTTP-команд

Большинство ASP.NET-страниц не проектировалось с учетом HTTP-команд; вместо этого зачастую применяли «транзакционный» подход в определении исходной версии кода. Это может затруднить связывание функциональности страницы с одной из HTTP-команд (или вынудить вас создать сложный post-метод, поддерживающий различные виды обработки).

Для обработки любой функциональности, ориентированной на транзакции, можно добавить маршрут, указывающий некий метод (называемый операцией) в контроллер по имени, а не по HTTP-типу. В следующем примере определяется URL, который направляет запрос методу с именем AssignCustomerToOrder и извлекает CustID и OrderID из URL (в отличие от POST методы, сопоставленные с другими HTTP-командами, могут принимать несколько параметров):

RouteTable.Routes.MapHttpRoute(
  "CustomerManagementAssign",
  "CustomerManagement/Assign/{CustID}/{OrderID}",
  new { Controller = "Customer", Action="AssignCustomerToOrder" },
  new { httpMethod = new HttpMethodConstraint("Get") }
  );

Это объявление для метода, которые принимает параметры, извлеченные из URL:

[HttpGet]
public HttpResponseMessage AssignCustomerToOrder(
  string CustID, string OrderID)
{

Функция перехвата, подключенная к соответствующему клиентскому событию, использует jQuery, чтобы получить функцию, которая передает URL с правильными компонентами:

function AssignOrder() {
  $.get('CustomerManagement/Assign/' +
    $("#CustomerID").val() + "/" + "A123",
    function (data, status) {
      $("#Messages").text(status);
      });
  return false;
}

Итак, рефакторинг файла кода для традиционной ASPX-страницы с целью переноса его кода в контроллер Web API — задача далеко не тривиальная. Однако гибкость ASP.NET Web API, ее мощные средства связывания HTTP-данных с .NET-объектами и способность использовать стандарты HTTP открывает потенциальную возможность для переноса существующих приложений на модель MVC/TDD и попутно позволяет увеличить масштабируемость за счет введения в страницы поддержки AJAX. Она также предоставляет парадигму для создания новых приложений ASP.NET, использующих продуктивность Web Forms и функциональность ASP.NET Web API.

Автор: Питер Вогел  •  Иcточник: MSDN Magazine  •  Опубликована: 16.08.2013
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER
Теги:   Web Forms.


Оценить статью:
Вверх
Комментарии посетителей
Комментарии отключены. С вопросами по статьям обращайтесь в форум.