Клиент для WebAPI

Уже много сказано о том, как создавать свои API на основе ASP.NET WebAPI и существенно меньше о том, как работать с этими сервисами со стороны клиента. Это и понятно, ведь часто потребителями этих сервисов выступает клиентский JavaScript, который умеет работать с JSON "из коробки". Тем не менее, случается и так, что клиентом должно быть .NET-приложение.

Удивительно, но несколько раз я встречал в коде, когда .NET-приложение взаимодействует с сервером при помощи HttpClient, а потом пытается вручную разбирать JSON/XML, пытаться проверять тип данных и т.п. Такой подход ведет к усложнению коду и ошибкам. Вместо этого можно воспользоваться уже готовой библиотекой, в которой это уже реализовано.

Создаем приложение, добавляем HttpClient, загружаем содержимое ответа с сервера:

using (var http = new HttpClient())
{
  var result = await http.GetAsync(new Uri("http://localhost:40139/api/users/get"));
  result.EnsureSuccessStatusCode();

  // ...
}

Устанавливаем Microsoft.AspNet.WebApi.Client:

Install-Package Microsoft.AspNet.WebApi.Client

Добавляем объект, описывающий сущность, возвращаемую сервером:

public class User
{
  public string Name { get; set; }
  public string Email { get; set; }
}

После получения ответа с сервера, распакуем его непосредственно в эти объекты:

using (var http = new HttpClient())
{
  var result = await http.GetAsync(new Uri("http://localhost:40139/api/users/get"));
  result.EnsureSuccessStatusCode();

  var users = await result.Content.ReadAsAsync<IEnumerable<User>>();

  foreach (var user in users)
  {
    // ...
  }
}

Как видно, мы не выполняем никаких действий по парсингу и преобразованию ответа.

Если предполагается, что сервер может вернуть результат в разных форматах, можно определить список форматировщиков, которые будут использоваться при распозновании ответа:

var users = await result.Content.ReadAsAsync<IEnumerable<User>>(
  new MediaTypeFormatter[]
  {
      new JsonMediaTypeFormatter(),
      new XmlMediaTypeFormatter()
  });

Можно не только получать данные с сервера, но и отправлять их обратно:

using (var http = new HttpClient())
{
  var result = await http.PostAsync(
    "http://localhost:40139/api/users/create",
    new User { Name = "User1", Email = "[email protected]" },
    new JsonMediaTypeFormatter());

  result.EnsureSuccessStatusCode();
}

Явно указывать используемый форматировщик необязательно. Вместо этого можно использовать перегруженные методы PostAs<>, например PostAsJsonAsync:

using (var http = new HttpClient())
{
  var result = await http.PostAsJsonAsync(
    "http://localhost:40139/api/users/create",
    new User { Name = "User1", Email = "[email protected]" });

  result.EnsureSuccessStatusCode();
}