Заметки о выпуске ASP.NET and Web Tools для Visual Studio 2013

От Майкрософт

В этом документе описывается выпуск ASP.NET и веб-инструментов для Visual Studio 2013.

Содержимое

Новые возможности в ASP.NET и веб-инструментах для Visual Studio 2013

Примечания по установке (Примечание по поддержке SAP № 1984787. Примечания по установке SUSE Linux Enterprise Server 12)

ASP.NET и веб-инструменты для Visual Studio 2013 упаковываются в основной установщик и можно скачать здесь.

Документация

Руководства и другие сведения о ASP.NET и веб-инструментах для Visual Studio 2013 доступны на веб-сайте ASP.NET.

Требования к программному обеспечению

для ASP.NET и веб-инструментов требуется Visual Studio 2013.

Новые возможности в ASP.NET и веб-инструментах для Visual Studio 2013

В следующих разделах описываются функции, которые были представлены в выпуске.

Одна ASP.NET

С выпуском Visual Studio 2013 мы сделали шаг к объединению опыта использования технологий ASP.NET, чтобы можно было легко смешивать и комбинировать их по своему усмотрению. Например, можно начать проект, используя MVC, и легко добавить страницы веб-форм в проект позже или создать структуру веб-API в проекте веб-форм. One ASP.NET направлено на упрощение для вас, как разработчика, выполнения любимых задач в ASP.NET. Независимо от того, какую технологию вы выбираете, вы можете иметь уверенность в том, что вы используете надежную базовую платформу One ASP.NET.

Новый интерфейс веб-проекта

Мы улучшили возможности создания веб-проектов в Visual Studio 2013. В диалоговом окне "Новый веб-проект ASP.NET" можно выбрать нужный тип проекта, настроить любое сочетание технологий (веб-формы, MVC, веб-API), настроить параметры проверки подлинности и добавить проект модульного теста.

Новый проект ASP.NET

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

  • Нет аутентификации
  • Индивидуальные учетные записи пользователей (учетная запись ASP.NET или вход через социальную сеть)
  • Учетные записи организации (Active Directory в интернет-приложении)
  • Проверка подлинности Windows (Active Directory в приложении интрасети)

Варианты проверки подлинности

Дополнительные сведения о новых параметрах проверки подлинности см. в разделе ASP.NET Identity далее в этом документе.

Инструментарий ASP.NET для создания шаблонов

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

В предыдущих версиях Visual Studio создание каркасов было ограничено проектами ASP.NET MVC. В Visual Studio 2013 теперь можно использовать шаблон для любого проекта ASP.NET, включая веб-формы. Visual Studio 2013 в настоящее время не поддерживает генерацию страниц для проекта Web Forms, но вы по-прежнему можете использовать шаблонизацию с Web Forms, добавив зависимости MVC в проект. В будущем обновлении будет добавлена поддержка создания страниц для веб-формы.

При использовании скэлдинга мы убеждаемся, что в проекте устанавливаются все необходимые зависимости. Например, если вы начинаете с проекта ASP.NET веб-формы, а затем используете шаблон для добавления контроллера веб-API, необходимые пакеты и ссылки NuGet добавляются в проект автоматически.

Чтобы добавить шаблон MVC в проект веб-формы, добавьте новый шаблонный элемент и выберите зависимости MVC 5 в диалоговом окне. Существует два варианта создания каркасов MVC: Минимальный и Полный. Если вы выберете Минимальный вариант, в проект добавляются только пакеты и ссылки NuGet для ASP.NET MVC. Если выбрать полный параметр, добавляются минимальные зависимости, а также необходимые файлы содержимого для проекта MVC.

Поддержка шаблонов асинхронных контроллеров использует новые асинхронные функции из Entity Framework 6.

Для получения дополнительной информации и учебных материалов см. Обзор Scaffolding в ASP.NET.

Новая функция "Ссылка браузера" позволяет подключать несколько браузеров к Visual Studio и обновлять их, нажав кнопку на панели инструментов. Вы можете подключить несколько браузеров к сайту разработки, включая мобильные эмуляторы, и нажать кнопку "Обновить", чтобы обновить все браузеры одновременно. Browser Link также предоставляет API, позволяя разработчикам создавать расширения для Browser Link.

Снимок экрана: меню Visual Studio с выделенным значком

Благодаря тому, что разработчики могут воспользоваться API ссылок браузера, можно создать очень сложные сценарии, пересекающие границы между Visual Studio и любым браузером, подключенным к нему. Web Essentials использует api для создания интегрированного интерфейса между Visual Studio и средствами разработчика браузера, удаленного управления мобильными эмуляторами и многое другое.

Улучшения веб-редактора Visual Studio

Visual Studio 2013 включает новый редактор HTML для файлов Razor и HTML-файлов в веб-приложениях. Новый редактор HTML предоставляет единую схему на основе HTML5. Он имеет автоматическое завершение фигурных скобок, пользовательский интерфейс jQuery и атрибут AngularJSense IntelliSense, группирование, идентификатор и имя класса Intellisense и другие улучшения, включая более высокую производительность, форматирование и SmartTags.

На следующем снимке экрана показано использование атрибута Bootstrap IntelliSense в редакторе HTML.

Intellisense в редакторе HTML

Visual Studio 2013 также поставляется со встроенными редакторами CoffeeScript и LESS. Редактор LESS поставляется со всеми крутыми функциями редактора CSS и имеет конкретную систему Intellisense для переменных и миксинов во всех LESS документах в цепочке @import.

Поддержка веб-приложений службы Azure App Service в Visual Studio

В Visual Studio 2013 с пакетом SDK Azure для .NET 2.2 можно использовать обозреватель серверов для взаимодействия непосредственно с удаленными веб-приложениями. Вы можете войти в учетную запись Azure, создать веб-приложения, настроить приложения, просмотреть журналы в режиме реального времени и многое другое. Вскоре после выпуска пакета SDK 2.2 вы сможете работать в режиме отладки удаленно в Azure. Большинство новых функций службы веб-приложений Azure App Service также работают в Visual Studio 2012 при установке текущей версии Azure SDK для .NET.

Дополнительные сведения см. на следующих ресурсах:

Улучшения веб-публикации

Visual Studio 2013 включает новые и улучшенные функции веб-публикации. Вот некоторые из них:

Дополнительные сведения о веб-развертывании ASP.NET см. на сайте ASP.NET.

NuGet 2.7

NuGet 2.7 содержит широкий набор новых функций, которые подробно описаны в заметках о выпуске NuGet 2.7.

Эта версия NuGet также удаляет необходимость предоставления явного согласия для функции восстановления пакетов NuGet для скачивания пакетов. Согласие (и связанный флажок в диалоговом окне настроек NuGet) теперь предоставляется путем установки NuGet. Теперь восстановление пакета просто работает по умолчанию.

Веб-формы ASP.NET

Одна ASP.NET

Шаблоны проектов веб-формы легко интегрируются с новым интерфейсом One ASP.NET. Вы можете добавить поддержку MVC и веб-API в проект веб-формы и настроить проверку подлинности с помощью мастера создания проекта One ASP.NET.

ASP.NET Identity

Шаблоны проектов веб-форм поддерживают новый фреймворк ASP.NET Identity. ** Кроме того, шаблоны теперь поддерживают создание проекта веб-форм для интрасети.

Bootstrap

Шаблоны веб-форм используют Bootstrap, чтобы обеспечить стильный и адаптивный внешний вид, который вы можете легко настроить.

ASP.NET MVC 5

Одна ASP.NET

Шаблоны проектов Web MVC легко интегрируются с новым интерфейсом One ASP.NET. Вы можете настроить проект MVC и настроить проверку подлинности с помощью мастера создания проекта One ASP.NET. Вводное руководство по ASP.NET MVC 5 можно найти на странице "Начало работы с ASP.NET MVC 5".

Сведения об обновлении проектов MVC 4 до MVC 5 см. в статье "Как обновить проект ASP.NET MVC 4 и Web API до ASP.NET MVC 5 и Web API 2".

ASP.NET Identity

Шаблоны проектов MVC были обновлены для использования ASP.NET Identity для проверки подлинности и управления удостоверениями. Руководство по проверке подлинности Facebook и Google, а также новый API членства можно найти в статье "Создание приложения ASP.NET MVC 5 с помощью Facebook и Google OAuth2 и OpenID Sign-on" и создание приложения ASP.NET MVC с проверкой подлинности и базой данных SQL и развертыванием в службе приложение Azure.

Bootstrap

Шаблон проекта MVC был обновлен, чтобы использовать Bootstrap для обеспечения элегантного и адаптивного внешнего вида, который вы можете легко настроить.

Фильтры проверки подлинности

Фильтры проверки подлинности — это новый тип фильтра в ASP.NET MVC, который выполняется до фильтров авторизации в конвейере MVC ASP.NET и позволяет указывать логику проверки подлинности для каждого действия, каждого контроллера или глобально для всех контроллеров. Фильтры аутентификации обрабатывают учетные данные в запросе и предоставляют соответствующего пользователя. Фильтры проверки подлинности также могут добавлять вызовы проверки подлинности в ответ на несанкционированные запросы.

Переопределения фильтров

Теперь можно переопределить фильтры, применяемые к заданному методу действия или контроллеру, указав фильтр переопределения. Фильтры переопределения указывают набор типов фильтров, которые не должны выполняться для данной области применения (действия или контроллера). Это позволяет настроить фильтры, которые применяются глобально, но затем исключить определенные глобальные фильтры из применения к определенным действиям или контроллерам.

Маршрутизация с помощью атрибутов

ASP.NET MVC теперь поддерживает маршрутизацию атрибутов, благодаря вкладу Тима Маккла, автора http://attributerouting.net. С помощью маршрутизации атрибутов можно указать маршруты, задав заметки о действиях и контроллерах.

Веб-API ASP.NET 2

Маршрутизация с помощью атрибутов

веб-API ASP.NET теперь поддерживает маршрутизацию атрибутов, благодаря вкладу Тима Маккалла, автораhttp://attributerouting.net. С помощью маршрутизации атрибутов можно указать маршруты веб-API, аннотируя действия и контроллеры следующим образом:

[RoutePrefix("orders")] 
public class OrdersController : ApiController 
{ 
    [Route("{id}")] 
    public Order Get(int id) { } 
    [Route("{id}/approve")] 
    public Order Approve(int id) { } 
}

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

public class MoviesController : ApiController 
{ 
    [Route("movies")] 
    public IEnumerable<Movie> Get() { } 
    [Route("actors/{actorId}/movies")] 
    public IEnumerable<Movie> GetByActor(int actorId) { } 
    [Route("directors/{directorId}/movies")] 
    public IEnumerable<Movie> GetByDirector(int directorId) { } 
}

Маршрутизация атрибутов также предоставляет удобный синтаксис для указания необязательных параметров, значений по умолчанию и ограничений маршрутов:

// Optional parameter
[Route("people/{name?}")]
// Default value
[Route("people/{name=Dan}")]
// Constraint: Alphabetic characters only. 
[Route("people/{name:alpha}")]

Дополнительные сведения о маршрутизации атрибутов см. в разделе "Маршрутизация атрибутов" в веб-API 2.

OAuth 2.0

Шаблоны проектов веб-API и одностраничного приложения теперь поддерживают авторизацию с помощью OAuth 2.0. OAuth 2.0 — это платформа для авторизации доступа клиента к защищенным ресурсам. Он работает для различных клиентов, включая браузеры и мобильные устройства.

Поддержка OAuth 2.0 основана на новом ПО промежуточного слоя безопасности, предоставляемом компонентами Microsoft OWIN для проверки подлинности носителя и реализацией роли сервера авторизации. Кроме того, клиенты могут быть авторизованы с помощью сервера авторизации организации, например Azure Active Directory или ADFS в Windows Server 2012 R2.

Улучшения OData

Поддержка $select, $expand, $batch и $value

веб-API ASP.NET OData теперь имеет полную поддержку $select, $expand и $value. Вы также можете использовать $batch для пакетного запроса и обработки наборов изменений.

Параметры $select и $expand позволяют изменить форму данных, возвращаемых из конечной точки OData. Для получения дополнительной информации см. Представление поддержки $select и $expand в Web API OData.

Улучшенная расширяемость

Теперь форматировщики OData расширяемы. Можно добавлять метаданные записей Atom, управлять записями именованных потоков и мультимедиа-ссылок, добавлять аннотации экземпляров и настраивать процесс генерации ссылок.

Поддержка без указания типов

Теперь можно создавать службы OData без необходимости определять типы CLR для типов сущностей. Вместо этого контроллеры OData могут принимать или возвращать экземпляры IEdmObject, которые форматировщики OData сериализуют/десериализуют.

Повторное использование существующей модели

Если у вас уже есть существующая модель данных сущности (EDM), теперь ее можно повторно использовать напрямую, а не создавать новую. Например, если вы используете Entity Framework, вы можете использовать EDM, который создает для вас EF.

Запрос пакетной обработки

Пакетирование запросов объединяет несколько операций в один HTTP POST-запрос, чтобы уменьшить сетевой трафик и обеспечить более плавный, менее разговорчивый пользовательский интерфейс. веб-API ASP.NET теперь поддерживает несколько стратегий пакетной обработки запросов:

  • Используйте конечную точку $batch службы OData.
  • Упаковывание нескольких запросов в один многопартийный запрос MIME.
  • Используйте пользовательский формат пакетной обработки.

Чтобы включить пакетную обработку запросов, просто добавьте маршрут с обработчиком пакетной обработки в конфигурацию веб-API:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
        config.Routes.MapHttpBatchRoute( 
            routeName: "WebApiBatch", 
            routeTemplate: "api/batch", 
            batchHandler: new DefaultHttpBatchHandler(GlobalConfiguration.DefaultServer)); 
    } 
}

Вы также можете контролировать, выполняются ли запросы последовательно или в любом порядке.

Переносимый клиент веб-API ASP.NET

Теперь вы можете использовать клиент веб-API ASP.NET для создания переносимых библиотек классов, которые работают в магазине Windows и приложениях Windows Phone 8. Вы также можете создавать переносимые форматировщики, которые можно совместно использовать между клиентом и сервером.

Улучшенная тестируемость

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

IHttpActionResult

Теперь можно реализовать IHttpActionResult, чтобы инкапсулировать результат методов действий веб-API. IHttpActionResult, возвращаемый методом действия веб-API, выполняется средой ASP.NET Web API, чтобы создать результирующее сообщение ответа. IHttpActionResult может быть возвращен из любого метода Web API для упрощения модульного тестирования вашей реализации Web API. Для удобства некоторые реализации IHttpActionResult предоставляются из коробки, включая результаты для возврата определенных кодов состояния, отформатированного содержимого или ответов с согласованием содержимого.

HttpRequestContext

Новый HttpRequestContext отслеживает любое состояние, связанное с запросом, но которое не сразу доступно из самого запроса. Например, можно использовать HttpRequestContext для получения данных маршрута, принципала, связанного с запросом, клиентского сертификата, UrlHelper и корневого каталога виртуального пути. Вы можете легко создать HttpRequestContext для модульного тестирования.

Так как главный объект для запроса передается с запросом вместо зависимости от Thread.CurrentPrincipal, главный объект теперь доступен на протяжении всего времени выполнения запроса, пока он находится в конвейере веб-API.

Общий доступ к ресурсам из разных источников (CORS)

Благодаря еще одному большому вкладу Брок Аллен, ASP.NET теперь полностью поддерживает общий доступ к запросам между источниками (CORS).

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

Веб-API 2 теперь поддерживает CORS, включая автоматическую обработку предварительных запросов (preflight requests). Дополнительные сведения см. в статье «Активация запросов между источниками в веб-API ASP.NET».

Фильтры проверки подлинности

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

Переопределения фильтров

Теперь можно переопределить фильтры, применяемые к заданному методу действия или контроллеру, указав фильтр переопределения. Переопределения фильтров указывают набор типов фильтров, которые не должны выполняться для определенной области применения (действия или контроллера). Это позволяет добавлять глобальные фильтры, а затем исключать некоторые из определенных действий или контроллеров.

Интеграция OWIN

веб-API ASP.NET теперь полностью поддерживает OWIN и может работать на любом узле, поддерживающем OWIN. Также включён фильтр HostAuthenticationFilter, который обеспечивает интеграцию с системой проверки подлинности OWIN.

Интеграция OWIN позволяет самостоятельно размещать веб-API в собственном процессе вместе с другими ПО промежуточного слоя OWIN, такими как SignalR. Дополнительные сведения см. в разделе «Использование OWIN для самостоятельного хостинга ASP.NET Web API».

ASP.NET SignalR 2.0

В следующих разделах описаны функции SignalR 2.0.

Пример обновления существующего проекта 1.x до SignalR 2.0 см. в разделе "Обновление проекта SignalR 1.x".

Создано на основе OWIN

SignalR 2.0 полностью построен на OWIN (открытый веб-интерфейс для .NET). Это изменение делает процесс установки для SignalR гораздо более согласованным между веб-размещенными и автономными приложениями SignalR, но также требует ряда изменений API.

MapHubs и MapConnection теперь MapSignalR

Для совместимости со стандартами OWIN эти методы были переименованы на MapSignalR. MapSignalR Вызывается без параметров, сопоставляет все концентраторы (как в версии 1.x с MapHubs); для сопоставления отдельных PersistentConnection, укажите тип соединения в качестве параметра типа, а расширение URL-адреса соединения — в качестве первого аргумента.

Метод MapSignalR вызывается в классе запуска Owin. Visual Studio 2013 содержит новый шаблон для класса запуска Owin; Чтобы использовать этот шаблон, сделайте следующее:

  1. Щелкните проект правой кнопкой мыши
  2. Выберите " Добавить", "Создать элемент" ...
  3. Выберите класс Owin Startup. Назовите новый класс Startup.cs.

В веб-приложении класс запуска Owin, содержащий метод MapSignalR, затем добавляется в процесс запуска Owin с помощью записи в узле параметров приложения файла Web.Config, как показано ниже.

В локальном приложении класс Startup передается в качестве параметра WebApp.Start типа метода.

Сопоставление узлов и соединений в SignalR 1.x (из глобального файла приложения в веб-приложении):

protected void Application_Start(object sender, EventArgs e) 
{
    // Map all hubs to "/signalr"
    RouteTable.Routes.MapHubs();
    // Map the Echo PersistentConnection to "/echo"
    RouteTable.Routes.MapConnection<myconnection>("echo", "/echo");
}

Сопоставление хабов и подключений в SignalR 2.0 (из класса запуска Owin):

using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(MyWebApplication.Startup))]

namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Map all hubs to "/signalr"
            app.MapSignalR();
            // Map the Echo PersistentConnection to "/echo"
            app.MapSignalR<echoconnection>("/echo");
        }
    }
}

В локальном приложении класс Startup передается в качестве параметра типа для WebApp.Start метода, как показано ниже.

string url = "http://localhost:8080";
using (WebApp.Start<startup>(url))
{
    Console.WriteLine("Server running on {0}", url);
    Console.ReadLine();
}

Поддержка между доменами

В SignalR 1.x междоменные запросы контролируются одним флагом EnableCrossDomain. Этот флаг управляет запросами JSONP и CORS. Для повышения гибкости все службы поддержки CORS были удалены из серверного компонента SignalR (клиенты JavaScript по-прежнему используют CORS обычно, если он обнаруживает, что браузер поддерживает его), а новое ПО промежуточного слоя OWIN было доступно для поддержки этих сценариев.

В SignalR 2.0, если в клиенте требуется JSONP (для поддержки междоменных запросов в старых браузерах), необходимо явно включить его, установив EnableJSONP для HubConfiguration объекта значение true, как показано ниже. JSONP отключен по умолчанию, так как он менее безопасный, чем CORS.

Чтобы добавить новое ПО промежуточного слоя CORS в SignalR 2.0, добавьте библиотеку Microsoft.Owin.Cors в проект и вызовите UseCors перед ПО промежуточного слоя SignalR, как показано в разделе ниже.

Добавление Microsoft.Owin.Cors в проект: чтобы установить эту библиотеку, выполните следующую команду в консоли диспетчер пакетов:

Install-Package Microsoft.Owin.Cors

Эта команда добавит в проект версию пакета версии 2.0.0.

Вызов UseCors

В следующих фрагментах кода показано, как реализовать междоменные подключения в SignalR 1.x и 2.0.

Реализация междоменных запросов в SignalR 1.x (из глобального файла приложения)

protected void Application_Start(object sender, EventArgs e) 
{
    var hubConfiguration = new HubConfiguration();
    hubConfiguration.EnableCrossDomain = true;
    RouteTable.Routes.MapHubs(hubConfiguration);
}

Реализация междоменных запросов в SignalR 2.0 (из файла кода C#)

В следующем коде показано, как включить CORS или JSONP в проекте SignalR 2.0. Этот пример кода использует Map и RunSignalR вместо MapSignalRэтого, чтобы ПО промежуточного слоя CORS выполнялось только для запросов SignalR, требующих поддержки CORS (а не для всего трафика по пути, указанному в MapSignalR.), Map также можно использовать для любого другого ПО промежуточного слоя, которое должно выполняться для определенного префикса URL-адреса, а не для всего приложения.

using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Owin;

[assembly: OwinStartup(typeof(MyWebApplication.Startup))]

namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Branch the pipeline here for requests that start with "/signalr"
            app.Map("/signalr", map =>
            {
                // Setup the CORS middleware to run before SignalR.
                // By default this will allow all origins. You can 
                // configure the set of origins and/or http verbs by
                // providing a cors options with a different policy.
                map.UseCors(CorsOptions.AllowAll);
                var hubConfiguration = new HubConfiguration 
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    // EnableJSONP = true
                };
                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });
        }
    }
}

Поддержка iOS и Android через MonoTouch и MonoDroid

Важный

Xamarin.Android, Xamarin.iOS, Xamarin.Mac теперь интегрированы непосредственно в .NET (начиная с .NET 6) в качестве .NET для Android, .NET для iOS и .NET для macOS. Если вы создаете эти типы проектов сегодня, они должны быть обновлены до проектов в стиле пакета SDK для .NET для продолжения поддержки. Дополнительные сведения об обновлении проектов Xamarin до .NET см. в документации по обновлению с Xamarin до .NET & .NET MAUI.

Добавлена поддержка для клиентов iOS и Android с помощью компонентов MonoTouch и MonoDroid из библиотеки Xamarin. Дополнительные сведения об их использовании см. в разделе "Использование компонентов Xamarin". Эти компоненты будут доступны в Xamarin Store при доступности выпуска SignalR RTW.

### Переносимый клиент .NET

Чтобы упростить кроссплатформенную разработку, клиенты Silverlight, WinRT и Windows Phone были заменены одним переносимым клиентом .NET, поддерживающим следующие платформы:

  • NET 4.5
  • Silverlight 5
  • WinRT (.NET для приложений Магазина Windows)
  • Windows Phone 8

Новый пакет для самостоятельного хостинга

Теперь пакет NuGet упрощает работу с приложением SignalR Self-Host (приложения SignalR, размещенные в процессе или другом приложении, а не размещенными на веб-сервере). Чтобы обновить проект самообслуживания, созданный с помощью SignalR 1.x, удалите пакет Microsoft.AspNet.SignalR.Owin и добавьте пакет Microsoft.AspNet.SignalR.SelfHost. Дополнительные сведения о начале работы с пакетом для самостоятельного размещения см. в руководстве SignalR Самостоятельное размещение.

Поддержка сервера с обратной совместимостью

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

Удалена поддержка сервера для .NET 4.0

SignalR 2.0 снизил поддержку взаимодействия сервера с .NET 4.0. .NET 4.5 должен использоваться с серверами SignalR 2.0. По-прежнему существует клиент .NET 4.0 для SignalR 2.0.

Отправка сообщения в список клиентов и групп

В SignalR 2.0 можно отправить сообщение с помощью списка идентификаторов клиента и групп. В следующих фрагментах кода показано, как это сделать.

Отправка сообщения в список клиентов и групп с помощью PersistentConnection

using Microsoft.AspNet.SignalR;
using System.Collections.Generic;
public class ChatConnection : PersistentConnection
{
    static List<string> ConnectionIds = new List<string>();
    static List<string> groups = new List<string>{"chatGroup", "chatGroup2"};
    protected override System.Threading.Tasks.Task OnReceived(IRequest request, string connectionId, string data)
    {
        Connection.Send(ConnectionIds, data);
        Groups.Send(groups, data);
        return base.OnReceived(request, connectionId, data);
    }
    protected override System.Threading.Tasks.Task OnConnected(IRequest request, string connectionId)
    {
        ConnectionIds.Add(connectionId);
        Groups.Add(connectionId, "chatGroup");
        return base.OnConnected(request, connectionId);
    }
    protected override System.Threading.Tasks.Task OnDisconnected(IRequest request, string connectionId)
    {
        ConnectionIds.Remove(connectionId);
        return base.OnDisconnected(request, connectionId);
    }
}

Отправка сообщения в список клиентов и групп с помощью Центров

using Microsoft.AspNet.SignalR;
using System.Collections.Generic;
public class ChatHub : Hub
{
    static List<string> ConnectionIds = new List<string>();
    static List<string> groups = new List<string> { "chatGroup", "chatGroup2" };
    public void Send(string name, string message)
    {
        // Call the broadcastMessage method to update clients.
        Clients.Clients(ConnectionIds).broadcastMessage(name, message);
        Clients.Groups(groups).broadcastMessage(name, message);
    }
    public override System.Threading.Tasks.Task OnConnected()
    {
        ConnectionIds.Add(Context.ConnectionId);
        Groups.Add(Context.ConnectionId, "chatGroup");
        return base.OnConnected();
    }
    public override System.Threading.Tasks.Task OnDisconnected()
    {
        ConnectionIds.Remove(Context.ConnectionId);
        return base.OnDisconnected();
    }
}

Отправка сообщения конкретному пользователю

Эта функция позволяет пользователям указать, какой идентификатор пользователя основан на IRequest с помощью нового интерфейса IUserIdProvider:

Интерфейс IUserIdProvider

public interface IUserIdProvider
{
    string GetUserId(IRequest request);
}

По умолчанию будет реализация, которая использует IPrincipal.Identity.Name пользователя в качестве имени пользователя.

В центрах вы сможете отправлять сообщения этим пользователям с помощью нового API:

Использование API Clients.User

public class MyHub : Hub
{
    public void Send(string userId, string message)
    {
        Clients.User(userId).send(message);
    }
}

Улучшена поддержка обработки ошибок

Теперь пользователи могут вызывать HubException из любого вызова концентратора. Конструктор HubException может принимать строковое сообщение и объект с дополнительными данными об ошибках. SignalR автоматически сериализует исключение и отправляет его клиенту, где он будет использоваться для отклонения или сбоя вызова метода концентратора.

Настройка отображения подробных исключений хаба не влияет на то, отправляется ли HubException клиенту; оно всегда отправляется.

Серверный код, демонстрирующий отправку HubException клиенту

public class MyHub : Hub
{
    public void Send(string message)
    {
        if(message.Contains("<script>"))
        {
            throw new HubException("This message will flow to the client", new { user = Context.User.Identity.Name, message = message });
        }

        Clients.All.send(message);
    }
}

Клиентский код JavaScript, демонстрирующий реагирование на hubException, отправляемый с сервера

myHub.server.send("<script>")
            .fail(function (e) {
                if (e.source === 'HubException') {
                    console.log(e.message + ' : ' + e.data.user);
                }
            });

Клиентский код .NET, демонстрирующий реагирование на hubException, отправляемый с сервера

try
{
    await myHub.Invoke("Send", "<script>");
}
catch(HubException ex)
{
    Conosle.WriteLine(ex.Message);
}

Упрощение модульного тестирования центров

SignalR 2.0 включает интерфейс IHubCallerConnectionContext в концентраторах, который упрощает создание имитаций вызовов на стороне клиента. Приведенные ниже фрагменты кода демонстрируют использование этого интерфейса с популярными средствами тестирования xUnit.net и moq.

Модульное тестирование SignalR с xUnit.net

[Fact]
public void HubsAreMockableViaDynamic()
{
    bool sendCalled = false;
    var hub = new MyHub();
    var mockClients = new Mock<IHubCallerConnectionContext>();
    hub.Clients = mockClients.Object;
    dynamic all = new ExpandoObject();
    all.send = new Action<string>(message =>
    {
        sendCalled = true;
    });
    mockClients.Setup(m => m.All).Returns((ExpandoObject)all);
    hub.Send("foo");
    Assert.True(sendCalled);
}

Модульное тестирование SignalR с использованием moq

[Fact]
public interface IClientContract
{
    void send(string message);
}
public void HubsAreMockableViaType()
{
    var hub = new MyHub();
    var mockClients = new Mock<IHubCallerConnectionContext>();
    var all = new Mock<IClientContract>();
    hub.Clients = mockClients.Object;
    all.Setup(m => m.send(It.IsAny<string>())).Verifiable();
    mockClients.Setup(m => m.All).Returns(all.Object);
    hub.Send("foo");
    all.VerifyAll();

Обработка ошибок JavaScript

В SignalR 2.0 все обработчики ошибок JavaScript возвращают объекты ошибок JavaScript вместо сырых строк. Это позволяет SignalR передавать более подробные сведения обработчикам ошибок. Вы можете получить внутреннее исключение из свойства ошибки source.

Клиентский код JavaScript, обрабатывающий исключение Start.Fail

connection.start().fail(function(e) {
    console.log('The error is: ' + e.message);
});

ASP.NET Identity

Новая система членства ASP.NET

ASP.NET Identity — это новая система членства для приложений ASP.NET. ASP.NET Identity упрощает интеграцию данных профиля конкретного пользователя с данными приложения. ASP.NET Identity также позволяет выбрать модель сохраняемости для профилей пользователей в приложении. Данные можно сохранять в базе данных SQL Server или другом хранилище, в том числе хранилищах данных NoSQL , таких как таблица хранилища Azure. Для получения дополнительной информации см. раздел "Индивидуальные учетные записи пользователей" в Создание веб-проектов ASP.NET в Visual Studio 2013.

проверка подлинности на основе утверждений.

ASP.NET теперь поддерживает проверку подлинности на основе утверждений, где удостоверение пользователя представлено как набор утверждений от доверенного издателя. Пользователи могут аутентифицироваться с помощью имени пользователя и пароля, хранящихся в базе данных приложения, или с помощью поставщиков социальных удостоверений (например, учетные записи Microsoft, Facebook, Google, Twitter), или с использованием учетных записей организации через Azure Active Directory или службы федерации Active Directory (ADFS).

Интеграция с Azure Active Directory и Windows Server Active Directory

Теперь можно создать ASP.NET проекты, использующие Azure Active Directory или Windows Server Active Directory (AD) для проверки подлинности. Дополнительные сведения см. в статье "Учетные записи организации" в статье "Создание веб-проектов ASP.NET в Visual Studio 2013".

Интеграция OWIN

Аутентификация в ASP.NET теперь основана на промежуточном ПО OWIN, которое можно использовать на любом узле на основе OWIN. Дополнительные сведения о OWIN см. в следующем разделе компонентов Microsoft OWIN .

Компоненты Microsoft OWIN

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

Изменения, представленные в компонентах Microsoft OWIN (также известных как проект Katana), включают новые компоненты сервера и узла, новые вспомогательные библиотеки и ПО промежуточного слоя и новое ПО промежуточного слоя проверки подлинности.

Дополнительные сведения о OWIN и Katana см. в Что нового в OWIN и Katana.

Примечание. Приложения OWIN не могут выполняться в классическом режиме IIS; они должны выполняться в интегрированном режиме.

Примечание. Приложения OWIN должны выполняться в полном доверии.

Новые серверы и хосты

В этом выпуске добавлены новые компоненты для включения сценариев самообслуживания. Эти компоненты включают следующие пакеты NuGet:

  • Microsoft.Owin.Host.HttpListener. Предоставляет сервер OWIN, использующий HttpListener для прослушивания HTTP-запросов и перенаправления их в конвейер OWIN.
  • Microsoft.Owin.Hosting предоставляет библиотеку для разработчиков, желающих самостоятельно разместить конвейер OWIN в пользовательском процессе, например консольное приложение или службу Windows.
  • OwinHost. Предоставляет автономный исполняемый файл, который выполняет оболочку Microsoft.Owin.Hosting и позволяет самостоятельно размещать конвейер OWIN без необходимости писать пользовательское приложение узла.

Кроме того, пакет Microsoft.Owin.Host.SystemWeb теперь позволяет промежуточному программному обеспечению предоставлять указания серверу SystemWeb, сигнализируя, что это программное обеспечение следует вызывать на определенном этапе обработки в ASP.NET. Эта функция особенно полезна для промежуточного программного слоя аутентификации, который должен выполняться в начале конвейера ASP.NET.

Вспомогательные библиотеки и ПО промежуточного слоя

Хотя компоненты OWIN можно написать только с помощью определений функций и типов из спецификации OWIN, новый Microsoft.Owin пакет предоставляет более удобный набор абстракций. Этот пакет объединяет несколько более ранних пакетов (например, Owin.Extensions, Owin.Types) в одну хорошо структурированную объектную модель, которую затем можно легко использовать другими компонентами OWIN. На самом деле большинство компонентов Microsoft OWIN теперь используют этот пакет.

Примечание.

Приложения OWIN не могут выполняться в классическом режиме IIS. Они должны выполняться в интегрированном режиме.

Примечание.

Приложения OWIN должны выполняться в полном доверии.

Этот выпуск также включает пакет Microsoft.Owin.Diagnostics, который содержит промежуточное ПО для проверки работы приложения OWIN, а также промежуточное ПО для страниц ошибок, чтобы упростить расследование сбоев.

Компоненты проверки подлинности

Доступны следующие компоненты проверки подлинности.

  • Microsoft.Owin.Security.ActiveDirectory. Включает проверку подлинности с помощью локальных или облачных служб каталогов.
  • Microsoft.Owin.Security.Cookies включает проверку подлинности с помощью файлов cookie. Этот пакет был ранее назван Microsoft.Owin.Security.Forms.
  • Microsoft.Owin.Security.Facebook включает проверку подлинности с помощью службы OAuth Facebook.
  • Microsoft.Owin.Security.Google включает проверку подлинности с помощью службы OpenID Google.
  • Microsoft.Owin.Security.Jwt включает проверку подлинности с помощью токенов JWT.
  • Microsoft.Owin.Security.MicrosoftAccount включает проверку подлинности с помощью учетных записей Майкрософт.
  • Microsoft.Owin.Security.OAuth. Предоставляет сервер авторизации OAuth, а также ПО промежуточного слоя для проверки подлинности маркеров носителя.
  • Microsoft.Owin.Security.Twitter включает проверку подлинности с помощью службы OAuth в Twitter.

Этот выпуск также включает Microsoft.Owin.Cors пакет, содержащий ПО промежуточного слоя для обработки HTTP-запросов между источниками.

Примечание.

Поддержка подписывания JWT была удалена в окончательной версии Visual Studio 2013.

Entity Framework 6

Список новых функций и других изменений в Entity Framework 6 см. в разделе История версий Entity Framework.

ASP.NET Razor 3

ASP.NET Razor 3 включает следующие новые функции:

  • Поддержка редактирования вкладок. Ранее команда «Формат документа», автоматическая расстановка отступов и автоматическое форматирование в Visual Studio не работали правильно при использовании опции «Сохранить табуляции». Это изменение исправляет форматирование Visual Studio для кода Razor для форматирования вкладок.
  • Поддержка правил переопределения URL-адресов при создании ссылок.
  • Удаление прозрачного атрибута безопасности.

    Примечание.

    Это критическое изменение и делает Razor 3 несовместимым с MVC4 и более ранними версиями, в то время как Razor 2 несовместим с MVC5 или сборками, скомпилированных в MVC5.

=======

Приостановка приложения ASP.NET

ASP.NET App Suspend — это прорывная функция в платформе .NET Framework 4.5.1, которая радикально изменяет взаимодействие с пользователем и экономическую модель для хостинга большого числа сайтов ASP.NET на одном сервере. Дополнительные сведения см. в разделе ASP.NET App Suspend — адаптивный общий веб-хостинг .NET.

Известные проблемы и критические изменения

В этом разделе описываются известные проблемы и критические изменения в ASP.NET и веб-инструментах для Visual Studio 2013.

NuGet

  • Восстановление нового пакета не работает в Mono при использовании SLN-файла— будет исправлено в предстоящем nuget.exe загрузке и обновлении пакета NuGet.CommandLine.
  • Новое восстановление пакетов не работает с проектами Wix — это будет исправлено в предстоящем скачивании nuget.exe и обновлении пакета NuGet.CommandLine.

ASP.NET Web API

  1. ODataQueryOptions<T>.ApplyTo(IQueryable) не всегда возвращается IQueryable<T> , так как мы добавили поддержку $select и $expand.

    Наши предыдущие примеры для ODataQueryOptions<T> всегда приводили возвращаемое значение из ApplyTo в IQueryable<T>. Это работало ранее, так как поддерживаемые ранее параметры запроса ($filter, $orderby, , $skip) $topне изменяют форму запроса. Теперь, когда мы поддерживаем $select и $expand, возвращаемое значение из ApplyTo не всегда будет IQueryable<T>.

    // Sample ODataQueryOptions<T> usage from earlier
    public IQueryable<Customer> Get(ODataQueryOptions<Customer> query)
    {
        IQueryable<customer> result="query.ApplyTo(_customers)" as iqueryable<customer>; return result;
    }
    

    Если вы используете пример кода из более ранних версий, он будет продолжать работать, если клиент не отправляет $select и $expand. Тем не менее, если вы хотите поддерживать $select и $expand вам придется изменить этот код на этот.

    public IHttpActionResult Get(ODataQueryOptions<Customer> query)
    {
        IQueryable result = query.ApplyTo(_customers);
        return Ok(result, result.GetType());
    }
     
    private IHttpActionResult Ok(object content, Type type)
    {
        Type resultType = typeof(OkNegotiatedContentResult<>).MakeGenericType(type);
        return Activator.CreateInstance(resultType, content, this) as IHttpActionResult;
    }
    
  2. Request.Url или RequestContext.Url имеет значение NULL во время пакетного запроса

    В сценарии пакетной обработки URLHelper имеет значение NULL при доступе из Request.Url или RequestContext.Url.

    Решение этой проблемы заключается в создании нового экземпляра UrlHelper, как показано в следующем примере:

    Создание нового экземпляра UrlHelper

    if (RequestContext.Url == null)
    {
        RequestContext.Url = new UrlHelper(Request);
    }
    

ASP.NET MVC

  1. При использовании MVC5 и OrgAuth, если у вас есть представления, которые выполняют проверку AntiForgerToken, при публикации данных в представление может возникнуть следующая ошибка:

    Ошибка.

    Ошибка сервера в приложении "/"

    Утверждение типа http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier или https://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider отсутствует в предоставленном ClaimsIdentity. Чтобы включить поддержку маркера защиты от подделки с проверкой подлинности на основе утверждений, убедитесь, что настроенный поставщик утверждений предоставляет оба этих утверждения в экземплярах ClaimsIdentity, которые он создает. Если настроенный поставщик утверждений вместо этого использует другой тип утверждения в качестве уникального идентификатора, его можно настроить, задав статическое свойство AntiForgeryConfig.UniqueClaimTypeIdentifier.

    Решение:

    Добавьте следующую строку в Global.asax, чтобы исправить ее:

    AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;

    Это будет исправлено для следующего выпуска.

  2. После обновления приложения MVC4 до MVC5 создайте решение и запустите его. Вы увидите следующую ошибку:

    [A]System.Web.WebPages.Razor.Configuration.HostSection нельзя привести к [B]System.Web.WebPages.Razor.Configuration.HostSection. Тип A происходит из 'System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' в контексте 'Default' в расположении 'C:\windows\Microsoft.Net\assembly\GAC_MSIL\System.Web.WebPages.Razor\v4.0_2.0.0.0__31bf3856ad364e35\System.Web.WebPages.Razor.dll'. Тип B происходит из System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' в контексте "Default" в расположении "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\6d05bbd0\e8b5908e\assembly\dl3\c9cbca63\f8910382_6273ce01\System.Web.WebPages.Razor.dll".

    Чтобы устранить указанную выше ошибку, откройте все файлы web.config (включая файлы в папке Views) в проекте и выполните следующие действия:

    1. Обновите все вхождения версии 4.0.0.0 "System.Web.Mvc" на "5.0.0.0.0".

    2. Обновите все вхождения версии "2.0.0.0" для "System.Web.Helpers", "System.Web.WebPages" и "System.Web.WebPages.Razor" до "3.0.0.0".

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

      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
        </dependentAssembly>
        <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
        </dependentAssembly>
        <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages.Razor" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
        </dependentAssembly>
        <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-4.0.0.0" newVersion="5.0.0.0" />
      </dependentAssembly>
      

      Сведения об обновлении проектов MVC 4 до MVC 5 см. в статье "Как обновить проект ASP.NET MVC 4 и Web API до ASP.NET MVC 5 и Web API 2".

  3. При использовании проверки на стороне клиента с jQuery Unobtrusive Validation сообщение проверки иногда неверно для элемента ввода HTML с типом ='number'. Ошибка проверки для требуемого значения (поле "Возраст является обязательным") отображается, если введено недопустимое число вместо правильного сообщения о том, что требуется допустимое число.

    Эта проблема часто встречается с шаблонным кодом для модели с целым числом свойством в представлениях Create and Edit.

    Чтобы обойти эту проблему, измените помощника в редакторе:

    @Html.EditorFor(person => person.Age)

    Кому:

    @Html.TextBoxFor(person => person.Age)

  4. ASP.NET MVC 5 больше не поддерживает частичное доверие. Проекты, которые используют двоичные файлы MVC или WebAPI, должны удалить атрибут SecurityTransparent и атрибут AllowPartiallyTrustedCallers. Удаление этих атрибутов приведет к устранению ошибок компилятора, таких как приведенные ниже.

    Attempt by security transparent method ‘MyComponent' to access security critical type 'System.Web.Mvc.MvcHtmlString' failed. Assembly 'PagedList.Mvc, Version=4.3.0.0, Culture=neutral, PublicKeyToken=abbb863e9397c5e1' is marked with the AllowPartiallyTrustedCallersAttribute, and uses the level 2 security transparency model. Level 2 transparency causes all methods in AllowPartiallyTrustedCallers assemblies to become security transparent by default, which may be the cause of this exception.

    Обратите внимание, что из-за этого побочного эффекта нельзя использовать сборки 4.0 и 5.0 в одном приложении. Вам нужно обновить все из них до версии 5.0.

Шаблон SPA с авторизацией Facebook может привести к нестабильности в IE, пока веб-сайт размещен в зоне интрасети

Шаблон SPA предоставляет внешний вход в Facebook. При локальном запуске проекта, созданного с помощью шаблона, вход может вызвать сбой в работе Internet Explorer.

Решение.

  1. Размещение веб-сайта в зоне Интернета; или

  2. Проверьте сценарий в браузере, отличном от IE.

Формирование шаблонов веб-форм

Встроенные инструменты веб-форм удалены из VS2013 и будут доступны в будущем обновлении для Visual Studio. Однако вы по-прежнему можете использовать шаблон в проекте веб-формы путем добавления зависимостей MVC и создания шаблонов для MVC. Проект будет содержать сочетание веб-формы и MVC.

Чтобы добавить MVC в проект веб-формы, добавьте новый шаблонный элемент и выберите зависимости MVC 5. Выберите "Минимальный" или "Полный" в зависимости от того, нужны ли все файлы содержимого, например скрипты. Затем добавьте шаблонный элемент для MVC, который создаст представления и контроллер в проекте.

Шаблон MVC и веб-API — ошибка HTTP 404, не найдена

Если при добавлении шаблонного элемента в проект возникает ошибка, возможно, проект останется в несогласованном состоянии. Некоторые внесенные изменения будут откатаны, в то время как другие изменения, такие как установленные пакеты NuGet, не будут откатаны. Если изменения конфигурации маршрутизации отменяются, пользователи получат ошибку HTTP 404 при переходе к сформированным элементам.

Решение:

  • Чтобы устранить эту ошибку для MVC, добавьте новый шаблонный элемент и выберите зависимости MVC 5 (минимальное или полное). Этот процесс добавит все необходимые изменения в проект.

  • Чтобы устранить эту ошибку для веб-API, выполните указанные ниже действия.

    1. Добавьте в проект класс WebApiConfig.

      public static class WebApiConfig
      {
          public static void Register(HttpConfiguration config)
          {
              config.MapHttpAttributeRoutes();
              config.Routes.MapHttpRoute(
                  name: "DefaultApi",
                  routeTemplate: "api/{controller}/{id}",
                  defaults: new { id = RouteParameter.Optional }
              );
          }
      }
      
      Public Module WebApiConfig
          Public Sub Register(ByVal config As HttpConfiguration)
              config.MapHttpAttributeRoutes()
              config.Routes.MapHttpRoute(
                name:="DefaultApi",
                routeTemplate:="api/{controller}/{id}",
                defaults:=New With {.id = RouteParameter.Optional}
              )
          End Sub
      End Module
      
    2. Настройте WebApiConfig.Register в методе Application_Start в Global.asax следующим образом:

      public class WebApiApplication : System.Web.HttpApplication
      {
          protected void Application_Start()
          {
              GlobalConfiguration.Configure(WebApiConfig.Register);    
          }
      }
      
      Public Class WebApiApplication
           Inherits System.Web.HttpApplication
       
           Sub Application_Start()     
             GlobalConfiguration.Configure(AddressOf WebApiConfig.Register)       
           End Sub
      End Class