Книги онлайн и без регистрации » Разная литература » Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 398 399 400 401 402 403 404 405 406 407
Перейти на страницу:
заполняться из настроек таким же способом, как и информация об автодилере. Создайте в проекте AutoLot.Services новый каталог по имени ApiWrapper и добавьте в него файл класса ApiServiceSettings.cs. Имена свойств класса должны совпадать с именами свойств в разделе ApiServiceSettings файла appsettings.Development.json. Код класса показан ниже:

namespace AutoLot.Services.ApiWrapper

{

  public class ApiServiceSettings

  {

    public ApiServiceSettings() { }

    public string Uri { get; set; }

    public string CarBaseUri { get; set; }

    public string MakeBaseUri { get; set; }

  }

}

Оболочка службы API

В версии ASP.NET Core 2.1 появился интерфейс IHTTPClientFactory, который позволяет конфигурировать строго типизированные классы для вызова внутри служб REST. Создание строго типизированного класса дает возможность инкапсулировать все обращения к API в одном месте. Это централизует взаимодействие со службой, конфигурацию клиента HTTP, обработку ошибок и т.д. Затем класс можно добавить в контейнер DI для дальнейшего применения в приложении. Контейнер DI и реализация IHTTPClientFactory обрабатывают создание и освобождение HTTPClient.

Интерфейс IApiServiceWrapper

Интерфейс оболочки службы AutoLot содержит методы для обращения к службе AutoLot.Api. Создайте в каталоге ApiWrapper новый файл интерфейса IApiServiceWrapper.cs и приведите операторы using к следующему виду:

using System.Collections.Generic;

using System.Threading.Tasks;

using AutoLot.Models.Entities;

Модифицируйте код интерфейса, как показано ниже:

namespace AutoLot.Services.ApiWrapper

{

  public interface IApiServiceWrapper

  {

    Task<IList<Car>> GetCarsAsync();

    Task<IList<Car>> GetCarsByMakeAsync(int id);

    Task<Car> GetCarAsync(int id);

    Task<Car> AddCarAsync(Car entity);

    Task<Car> UpdateCarAsync(int id, Car entity);

    Task DeleteCarAsync(int id, Car entity);

    Task<IList<Make>> GetMakesAsync();

  }

}

Класс ApiServiceWrapper

Создайте в каталоге ApiWrapper проекта AutoLot.Services новый файл класса по имени ApiServiceWrapper.cs и модифицируйте его операторы using следующим образом:

using System;

using System.Collections.Generic;

using System.Net.Http;

using System.Net.Http.Json;

using System.Text;

using System.Text.Json;

using System.Threading.Tasks;

using AutoLot.Models.Entities;

using Microsoft.Extensions.Options;

Сделайте класс открытым и добавьте конструктор, который принимает экземпляр HttpClient и экземпляр реализации IOptionsMonitor<ApiServiceSettings>. Создайте закрытую переменную типа ServiceSettings и присвойте ей значение с использованием свойства CurrentValue параметра IOptionsMonitor<Service Settings>. Код показан ниже:

public class ApiServiceWrapper : IApiServiceWrapper

{

  private readonly HttpClient _client;

  private readonly ApiServiceSettings _settings;

  public ApiServiceWrapper(HttpClient client,

      IOptionsMonitor<ApiServiceSettings> settings)

  {

      _settings = settings.CurrentValue;

    _client = client;

    _client/BaseAddress = new Uri(_settins.Uri);

  }

}

На заметку! В последующих разделах содержится много кода без какой-либо обработки ошибок. Поступать так настоятельно не рекомендуется! Обработка ошибок здесь опущена из-за экономии пространства.

Внутренние поддерживающие методы

Класс содержит четыре поддерживающих метода, которые применяются открытыми методами.

Вспомогательные методы для POST и PUT

Следующие методы являются оболочками для связанных методов HttpClient:

internal async Task<HttpResponseMessage> PostAsJson(string uri, string json)

{

  return await _client.PostAsync(uri, new StringContent(json, Encoding.UTF8,

                                 "application/json"));

}

internal async Task<HttpResponseMessage> PutAsJson(string uri, string json)

{

  return await _client.PutAsync(uri, new StringContent(json, Encoding.UTF8,

                                "application/json"));

}

Вспомогательный метод для DELETE

Последний вспомогательный метод используется для выполнения НТТР-метода DELETE. Спецификация HTTP 1.1 (и более поздние версии) позволяет передавать тело в HTTP-методе DELETE, но для этого пока еще не предусмотрено расширяющего метода HttpClient. Экземпляр HttpRequestMessage потребуется создавать с нуля.

Первым делом необходимо создать сообщение запроса с применением инициализации объектов для установки Content, Method и RequestUri. Затем сообщение отправляется, после чего ответ возвращается вызывающему коду. Вот код метода:

internal async Task<HttpResponseMessage> DeleteAsJson(string uri, string json)

{

  HttpRequestMessage request = new HttpRequestMessage

  {

    Content = new StringContent(json, Encoding.UTF8, "application/json"),

    Method = HttpMethod.Delete,

    RequestUri = new Uri(uri)

  };

  return await _client.SendAsync(request);

}

Вызовы HTTP-метода GET

Есть четыре вызова НТТР-метода GET: один для получения всех записей Car, один для получения записей Car по производителю Make, один для получения одиночной записи Car и один для получения всех записей Make. Все они следуют тому же самому шаблону. Метод GetAsync() вызывается для возвращения экземпляра HttpResponseMessage. Успешность или неудача вызова проверяется с помощью метода EnsureSuccessStatusCode(), который генерирует исключение, если вызов не возвратил код состояния успеха. Затем тело ответа сериализируется в тип свойства (сущность или список сущностей) и возвращается вызывающему коду. Ниже приведен код всех методов:

public async Task<IList<Car>> GetCarsAsync()

{

  var response = await _client.GetAsync($"{_settings.Uri}{_settings.CarBaseUri}");

  response.EnsureSuccessStatusCode();

  var result = await response.Content.ReadFromJsonAsync<IList<Car>>();

  return result;

}

public async Task<IList<Car>> GetCarsByMakeAsync(int id)

{

 var response = await

  _client.GetAsync($"{_settings.Uri}{_settings.CarBaseUri}/bymake/{id}");

  response.EnsureSuccessStatusCode();

  var result = await response.Content.ReadFromJsonAsync<IList<Car>>();

  return result;

}

public async Task<Car> GetCarAsync(int id)

{

  var response = await

  _client.GetAsync($"{_settings.Uri}{_settings.CarBaseUri}/{id}");

  response.EnsureSuccessStatusCode();

  var result = await response.Content.ReadFromJsonAsync<Car>();

  return result;

}

public async Task<IList<Make>> GetMakesAsync()

{

  var response = await

  _client.GetAsync($"{_settings.Uri}{_settings.MakeBaseUri}");

  response.EnsureSuccessStatusCode();

  var result = await response.Content.ReadFromJsonAsync<IList<Make>>();

  return result;

}

Вызов HTTP-метода POST

Метод для добавления записи Car использует HTTP-метод POST. Он применяет вспомогательный метод для отправки сущности в формате JSON и возвращает запись Car из тела ответа. Вот его код:

public async Task<Car> AddCarAsync(Car entity)

{

  var response = await PostAsJson($"{_settings.Uri}{_settings.CarBaseUri}",

    JsonSerializer.Serialize(entity));

  if (response == null)

  {

    throw new Exception("Unable to communicate with the service");

  }

  return await response.Content.ReadFromJsonAsync<Car>();

}

1 ... 398 399 400 401 402 403 404 405 406 407
Перейти на страницу:

Комментарии
Минимальная длина комментария - 20 знаков. В коментария нецензурная лексика и оскорбления ЗАПРЕЩЕНЫ! Уважайте себя и других!
Комментариев еще нет. Хотите быть первым?