Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен
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>();
}
Откройте для себя мир чтения на siteknig.com - месте, где каждая книга оживает прямо в браузере. Здесь вас уже ждёт произведение Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен, относящееся к жанру Программирование. Никаких регистраций, никаких преград - только вы и история, доступная в полном формате. Наш литературный портал создан для тех, кто любит комфорт: хотите читать с телефона - пожалуйста; предпочитаете ноутбук - идеально! Все книги открываются моментально и представлены полностью, без сокращений и скрытых страниц. Каталог жанров поможет вам быстро найти что-то по настроению: увлекательный роман, динамичное фэнтези, глубокую классику или лёгкое чтение перед сном. Мы ежедневно расширяем библиотеку, добавляя новые произведения, чтобы вам всегда было что открыть "на потом". Сегодня на siteknig.com доступно более 200000 книг - и каждая готова стать вашей новой любимой. Просто выбирайте, открывайте и наслаждайтесь чтением там, где вам удобно.


