Как отловить ошибку API в HttpClient?

Как отловить ошибку API в HttpClient? Ошибки 400..., 500....

Отправляю запросы к API.
Если проблемы на сервере в if(!response.IsSuccessStatusCode) значение IsSuccessStatusCode равно ок (200).
Т.е. через это выражение я не могу получить что у сервера проблемы.

А по факту я получаю JSON с ошибкой

{
  "ok": false,
  "error": {
    "error_code": 406,
    "message": "Please enter [data]."
  }
}

Если сервер работает без ошибок и я получаю данные с сервера то получаю json типа:

{
  "ok": true,
  "uuid": "4564-dc12-4d8c-a919-e46541a",
  "balance": {
    "cost": 7,
    "final": 1397
  },
  "status": "SUCCEEDED",
  "execution_time": 1.68081,
  "data": {
    "total": 4,
    "result": [
    дальше идут данные 

Или после каждого запроса нужно делать DeserializeObject и проверять соответсвует ли он JSON ошибки?

Фрагмент кода

private async Task Execute(List<string> listID)
{
    try
    {      
        foreach (var idParam in list)
        {
            
            string url = $"{apiUrl}?id={idParam}";
            
            string resultContent = await _apiClientService.GetContent(url, apiKey);
 
            var user = JsonConvert.DeserializeObject<User>(resultContent);
            
            string line = $"{idParam} | {user.Name} | {user.DateBrth}"; 
            File.WriteAllText("example.txt", line);
                           
        }
    }
    catch (Exception ex)
    {
        string ms = ex.Message;
        _log.LogWithDetailedInfo(ms);
 
        _messageService.ShowOk("Процесс `ID`. Ошибка", ms);
        throw;
    }
}
public async Task<string> GetContent(string url, string apiKey)
{
    string urlResult = url.Replace("\r\n", "").Replace("\n", "");
 
    string content = "";
    try
    {
        var _httpClient = new HttpClient();
        _httpClient.DefaultRequestHeaders.Add("Apikey", apiKey);
 
        var response = await _httpClient.GetAsync(urlResult);
     
 
        if (!response.IsSuccessStatusCode)
        {
            _log.LogWithDetailedInfo($"API error: {(int)response.StatusCode} - {response.ReasonPhrase}");
 
 
            return null;
        }
 
        content = await response.Content.ReadAsStringAsync();
        
    }
    catch (Exception ex)
    {
        string msg = ex.Message;
        _messageService.ShowOk("ApiClient.Service", msg);
    }
 
    return content;
 
}

Ответы (1 шт):

Автор решения: aepot

Берём вот этот json

{
  "ok": false,
  "error": {
    "error_code": 406,
    "message": "Please enter [data]."
  }
}

Пишем под него модель

public class ApiErrorResponse
{
    public bool Ok { get; set; }
    public ApiErrorInfo Error { get; set; }
}

public class ApiErrorInfo
{
    [JsonProperty("error_code")]
    public int Code { get; set; }
    public string Message { get; set; }
}

Далее как-то так

using var response = await _httpClient.GetAsync(urlResult);

if (!response.IsSuccessStatusCode)
{
    _log.LogWithDetailedInfo($"API error: {(int)response.StatusCode} - {response.ReasonPhrase}");

    return null;
}
content = await response.Content.ReadAsStringAsync();
ApiErrorResponse errorResponse = JsonConvert.DeserializeObject<ApiErrorResponse>(content);
if (!errorResponse.Ok)
{
    _log.LogWithDetailedInfo($"API error: {errorResponse.Error.Code} - {errorResponse.Error.Message}");
    string message = $"Ошибка при обращении в API: {errorResponse.Error.Code} ({errorResponse.Error.Message})";
    switch (errorResponse.Error.Code)
    {
        case 500:
            message = "Ошибка подключения к базе данных.";
            break;
        case 400:
            message = "Запрошенная версия API не существует.";
            break;
        case 401:
            message = "Проблема с ключом доступа.";
            break;
    }
    _messageService.ShowOk("ApiClient.Service", message);
    return null;
}

// Если всё ошибок нет, продолжаем 
ApiCompletedResponse completedResponse = JsonConvert.DeserializeObject<ApiCompletedResponse>(content);

// Продолжаем работать с `completedResponse`
→ Ссылка