| Предыдущая лекция | Следующая лекция | |
|---|---|---|
| Аутентификация и авторизация | Содержание |
Возвращаемся к основному проекту (список продукции).
Реализуем получение данных не через базу, а через АПИ с помощью HTTP-запросов.
На C# нам надо решить две задачи:
Для HTTP-запросов будем использовать встроенный класс HttpClient
var client = new HttpClient();
В АПИ мы использовали "базовую" авторизацию. В C# я не нашёл встроенных библиотек для облегчения формирования заголовка для "базовой" авторизации, но реализация не сложная - напишем сами.
Формируем base64-кодированную строку:
var basic = Convert.ToBase64String(
ASCIIEncoding.ASCII.GetBytes("admin:password"));
И добавляем заголовок нашему http-клиенту:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basic);
Теперь можно запрашивать данные.
У класса HttpClient все методы асинхронные, нужно понимать как работают async/await.
Но можно не заморачиваться и использовать свойство Result, которое вернет синхронный результат.
Напишем класс ApiDataPrivider:
Можно как обычно реализовать его "с нуля", реализуя интерфейс IDataProvider (в этом случае придется сразу писать все методы), но можно реализовать механизм наследования: сделать потомка класса DBDataProvider, постепенно переопределяя методы.
Ниже показана реализация одного метода класса, остальные перепишите сами. И не забудьте в конструкторе главного окна поменять инициализацию dataProvider: Global.dataProvider = new ApiDataProvider();
В базовом классе (DBDataProvider) нужно добавить методам модификатор virtual
public class ApiDataProvider: DBDataProvider
{
private static string baseUrl = "http://localhost:5000";
public override IEnumerable<Product> getProduct(int pageNum)
{
var client = new HttpClient();
var body = client.GetStringAsync(
$"{baseUrl}/product?pageNum={pageNum}"
).Result;
return JsonConvert.DeserializeObject<Product[]>(body);
}
}
Если вы используете авторизацию, то при запросе данных добавляйте заголовок:
var basic = Convert.ToBase64String(
ASCIIEncoding.ASCII.GetBytes("esmirnov:123456"));
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", basic);
Метод GetStringAsync возвращает объект Task<string>, т.е. задачу, которая выполняется в отдельном потоке и по завершении вернёт строку (тело ответа). Чтобы не возиться с асинхронностью, можно запросить свойство Result.
Для работы с JSON нужно установить NuGet пакет Newtonsoft.Json и использовать метод десериализации объекта:
return JsonConvert.DeserializeObject<Product[]>(body);
В общем случае может быть десериализован любой валидный JSON, но мы явно в угловых скобках указываем, что ожидаем массив продуктов.
// сначала запихиваем объект в JSON-строку.
var jsonString = JsonConvert.SerializeObject(product)
// создаём контент для http-запроса
var json = new StringContent(
jsonString,
Encoding.UTF8,
"application/json"
);
// и вызываем POST-запрос
var client = new HttpClient();
// не забываем добавить авторизацию
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", basic);
var result = client.PostAsync(
$"{baseUrl}/product",
json).Result;
Задание:
Полностью реализовать класс ApiDataProvider
| Предыдущая лекция | Следующая лекция | |
|---|---|---|
| Аутентификация и авторизация | Содержание |