Self-Host ASP.NET веб-API 1 (C#)

Майк Уосон

В этом руководстве показано, как разместить веб-API в консольном приложении. ASP.NET веб-API не требует IIS. Вы можете самостоятельно разместить веб-API в собственном процессе узла.

Новые приложения должны использовать OWIN для самостоятельного размещения веб-API. См. "Использование OWIN для самостоятельного хостинга ASP.NET Web API 2".

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

  • Веб-API 1
  • Visual Studio 2012 г.

Создание проекта консольного приложения

Запустите Visual Studio и выберите новый проект на начальной странице. Или в меню файла выберите Создать, а затем Project.

В области "Шаблоны " выберите "Установленные шаблоны " и разверните узел Visual C# . В разделе Visual C# выберите Windows. В списке шаблонов проектов выберите консольное приложение. Назовите проект "SelfHost" и нажмите кнопку "ОК".

Снимок экрана: диалоговое окно

Установка целевой платформы (Visual Studio 2010)

Если вы используете Visual Studio 2010, измените целевую платформу на .NET Framework 4.0. (По умолчанию шаблон проекта предназначен для профиля клиента .Net Framework.)

В обозревателе решений щелкните проект правой кнопкой мыши и выберите пункт "Свойства". В раскрывающемся списке целевой платформы измените целевую платформу на .NET Framework 4.0. При появлении запроса на применение изменения нажмите кнопку "Да".

Снимок экрана: окно обозревателя решений с раскрывающимся списком Target Framework с элементом dot NET Framework 4, выделенным синим цветом.

Установка диспетчера пакетов NuGet

Диспетчер пакетов NuGet — самый простой способ добавить сборки веб-API в проект non-ASP.NET.

Чтобы проверить, установлен ли диспетчер пакетов NuGet, щелкните меню "Сервис " в Visual Studio. Если отображается пункт меню NuGet Package Manager, то у вас есть диспетчер пакетов NuGet.

Чтобы установить диспетчер пакетов NuGet, выполните приведенные действия.

  1. Запустите Visual Studio.
  2. В меню "Сервис" выберите "Расширения" и "Обновления".
  3. В диалоговом окне "Расширения и обновления " выберите "Онлайн".
  4. Если вы не видите "Диспетчер пакетов NuGet", в поле поиска введите "диспетчер пакетов nuget".
  5. Выберите диспетчер пакетов NuGet и нажмите кнопку "Скачать".
  6. После завершения скачивания появится запрос на установку.
  7. После завершения установки может потребоваться перезапустить Visual Studio.

Снимок экрана: диалоговое окно

Добавить пакет веб-API NuGet

После установки диспетчера пакетов NuGet добавьте в проект пакет Web API Self-Host.

  1. В меню "Сервис" выберите Диспетчер пакетов NuGet. Примечание. Если этот пункт меню не отображается, убедитесь, что диспетчер пакетов NuGet установлен правильно.
  2. Выберите "Управление пакетами NuGet" для решения
  3. В диалоговом окне "Управление пакетами NugGet " выберите "Online".
  4. В поле поиска введите "Microsoft.AspNet.WebApi.SelfHost".
  5. Выберите пакет самообслуживания веб-API ASP.NET и нажмите кнопку "Установить".
  6. После установки пакета нажмите кнопку "Закрыть ", чтобы закрыть диалоговое окно.

Замечание

Не забудьте установить пакет с именем Microsoft.AspNet.WebApi.SelfHost, а не AspNetWebApi.SelfHost.

Снимок экрана диалогового окна

Создание модели и контроллера

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

Добавьте открытый класс с именем Product.

namespace SelfHost
{
    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }
}

Добавьте открытый класс с именем ProductsController. Наследуем этот класс от System.Web.Http.ApiController.

namespace SelfHost
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Web.Http;
    
    public class ProductsController : ApiController
    {
        Product[] products = new Product[]  
        {  
            new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },  
            new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },  
            new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }  
        };

        public IEnumerable<Product> GetAllProducts()
        {
            return products;
        }

        public Product GetProductById(int id)
        {
            var product = products.FirstOrDefault((p) => p.Id == id);
            if (product == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            return product;
        }

        public IEnumerable<Product> GetProductsByCategory(string category)
        {
            return products.Where(p => string.Equals(p.Category, category,
                    StringComparison.OrdinalIgnoreCase));
        }
    }
}

Дополнительные сведения о коде в этом контроллере см. в руководстве по началу работы . Этот контроллер определяет три действия GET:

URI Описание
/api/products Получите список всех продуктов.
/api/products/id Получите продукт по идентификатору.
/api/products/?category=категория Получение списка продуктов по категориям.

Размещение веб-API

Откройте файл Program.cs и добавьте следующие инструкции using:

using System.Web.Http;
using System.Web.Http.SelfHost;

Добавьте следующий код в класс Program .

var config = new HttpSelfHostConfiguration("http://localhost:8080");

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

using (HttpSelfHostServer server = new HttpSelfHostServer(config))
{
    server.OpenAsync().Wait();
    Console.WriteLine("Press Enter to quit.");
    Console.ReadLine();
}

(Необязательно) Добавление резервирования пространства имен URL-адреса HTTP

Это приложение прослушивает http://localhost:8080/. По умолчанию для прослушивания определенного HTTP-адреса требуются права администратора. При запуске руководства может возникнуть эта ошибка: "HTTP не удалось зарегистрировать URL-адрес http://+:8080/" Существует два способа избежать этой ошибки:

  • Запустите Visual Studio с повышенными правами администратора или
  • Используйте Netsh.exe, чтобы предоставить учетным записям разрешения для резервирования URL-адреса.

Чтобы использовать Netsh.exe, откройте командную строку с правами администратора и введите следующую команду:

netsh http add urlacl url=http://+:8080/ user=machine\username

где machine\username — ваша учетная запись пользователя.

После завершения самостоятельного размещения обязательно удалите резервирование:

netsh http delete urlacl url=http://+:8080/

Вызов веб-API из клиентского приложения (C#)

Давайте напишем простое консольное приложение, которое вызывает веб-API.

Добавьте новый проект консольного приложения в решение:

  • В обозревателе решений щелкните решение правой кнопкой мыши и выберите команду "Добавить новый проект".
  • Создайте консольное приложение с именем ClientApp.

Снимок экрана: обозреватель решений, на котором показаны пункты меню

Используйте диспетчер пакетов NuGet для добавления пакета основных библиотек веб-API ASP.NET:

  • В меню "Сервис" выберите Диспетчер пакетов NuGet.
  • Выберите "Управление пакетами NuGet" для решения
  • В диалоговом окне "Управление пакетами NuGet" выберите "Online".
  • В поле поиска введите Microsoft.AspNet.WebApi.Client.
  • Выберите пакет клиентских библиотек веб-API microsoft ASP.NET и нажмите кнопку "Установить".

Добавьте ссылку в ClientApp в проект SelfHost:

  • В обозревателе решений щелкните правой кнопкой мыши проект ClientApp.
  • Выберите "Добавить ссылку".
  • В диалоговом окне "Диспетчер ссылок" в разделе "Решение" выберите "Проекты".
  • Выберите проект SelfHost.
  • Нажмите кнопку ОК.

Снимок экрана диалогового окна Reference Manager с проектом Self Host, выделенным синим полем.

Откройте файл client/Program.cs. Добавьте следующую инструкцию using :

using System.Net.Http;

Добавьте статический экземпляр HttpClient :

namespace Client
{
    class Program
    {
        static HttpClient client = new HttpClient();
    }
}

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

static void ListAllProducts()
{
    HttpResponseMessage resp = client.GetAsync("api/products").Result;
    resp.EnsureSuccessStatusCode();

    var products = resp.Content.ReadAsAsync<IEnumerable<SelfHost.Product>>().Result;
    foreach (var p in products)
    {
        Console.WriteLine("{0} {1} {2} ({3})", p.Id, p.Name, p.Price, p.Category);
    }
}

static void ListProduct(int id)
{
    var resp = client.GetAsync(string.Format("api/products/{0}", id)).Result;
    resp.EnsureSuccessStatusCode();

    var product = resp.Content.ReadAsAsync<SelfHost.Product>().Result;
    Console.WriteLine("ID {0}: {1}", id, product.Name);
}

static void ListProducts(string category)
{
    Console.WriteLine("Products in '{0}':", category);

    string query = string.Format("api/products?category={0}", category);

    var resp = client.GetAsync(query).Result;
    resp.EnsureSuccessStatusCode();

    var products = resp.Content.ReadAsAsync<IEnumerable<SelfHost.Product>>().Result;
    foreach (var product in products)
    {
        Console.WriteLine(product.Name);
    }
}

Каждый из этих методов соответствует одному и тому же шаблону:

  1. Вызовите HttpClient.GetAsync , чтобы отправить запрос GET в соответствующий универсальный код ресурса (URI).
  2. Вызовите HttpResponseMessage.EnsureSuccessStatusCode. Этот метод создает исключение, если состояние ответа HTTP является кодом ошибки.
  3. Вызовите ReadAsAsync<T> для десериализации типа CLR из HTTP-ответа. Этот метод является методом расширения, определенным в System.Net.Http.HttpContentExtensions.

Методы GetAsync и ReadAsAsync являются асинхронными. Они возвращают объекты задачи , представляющие асинхронную операцию. Получение свойства Result блокирует поток до завершения операции.

Дополнительные сведения об использовании HttpClient, в том числе о том, как выполнять неблокирующие вызовы, см. в статье "Вызов веб-API из клиента .NET".

Перед вызовом этих методов установите значение свойства BaseAddress экземпляра HttpClient на "http://localhost:8080". Рассмотрим пример.

static void Main(string[] args)
{
    client.BaseAddress = new Uri("http://localhost:8080");

    ListAllProducts();
    ListProduct(1);
    ListProducts("toys");

    Console.WriteLine("Press Enter to quit.");
    Console.ReadLine();
}

Это должно вывести следующее. (Не забудьте сначала запустить приложение SelfHost.)

1 Tomato Soup 1.0 (Groceries)
2 Yo-yo 3.75 (Toys)
3 Hammer 16.99 (Hardware)
ID 1: Tomato Soup
Products in 'toys':
Yo-yo
Press Enter to quit.

Снимок экрана: окно консоли с выходным списком продуктов, связанных с I D и категориями.