Как извлечь пользовательский объект ошибки из неудачного вызова HttpClient?

#c# #.net-core #error-handling #asp.net-core-webapi

#c# #.net-core #обработка ошибок #asp.net-core-webapi

Вопрос:

Я совсем новичок.Net Core Web API и потратил несколько дней на поиск ответа, но не смог найти именно то, что я ищу. Что я хочу знать, так это как получить пользовательский объект, который передается из действия API обратно клиенту через ActionResult (BadRequest(), NotFound() … и т.д.)

Итак, я создал новый проект веб-API в VS2019 и обновил метод Get по умолчанию для WeatherForecastController следующим образом:

     [HttpGet]
    public ActionResult<IEnumerable<WeatherForecast>> Get()
    {
        return NotFound(new { Message = "Could not find data", Suggestion = "Refine your search" });
    }
 

При тестировании в Postman я могу получить ожидаемый результат Status = 404, а тело

     {
        "message": "Could not find data",
        "suggestion": "Refine your search"
    }
 

Но в клиентском проекте я просто не знаю, как я могу получить этот пользовательский объект ошибки.

Мой клиентский код выглядит следующим образом:

     public async Task OnGet()
    {
        try
        {
            HttpClient httpClient = new HttpClient();
            httpClient.BaseAddress = new Uri("https://localhost:44377/");
            WeatherForcasts = await httpClient.GetFromJsonAsync<WeatherForcast[]>("weatherforecast");
        }
        catch (HttpRequestException ex)
        {
            hasError = true;
        }
    }
 

Я понимаю, что если действие API не возвращает код состояния успеха (например, 200), то это вызовет исключение HttpRequestException. Но я не могу найти способ получить этот пользовательский объект ошибки из HttpRequestException.

Любая помощь будет очень признательна!

Ответ №1:

Измените свой код на это:

 public async Task OnGet()
    {
    
    using var client = new HttpClient(); 
    var baseAddress ="https://localhost:44377");
    client.BaseAddress = new Uri(baseAddress);
            
    var response= await client.GetAsync(baseAddress);
    var statusCode = response.StatusCode.ToString(); // shoud be "NotFound"
    var stringData = await response.Content.ReadAsStringAsync();
    var data= JsonConvert.DeserializeObject<object>(stringData);// should be 
// "{{"message":"Could not find data","suggestion": "Refine your search"}}"
           ....
        
    }
 

Комментарии:

1. Спасибо, Сергей. Я думаю, GetFromJsonAsync из System.Net.Http. Json, который должен упростить вызов API, не сможет обеспечить необходимую мне гибкость. Я с радостью взял ваш подход за основу для создания своего решения. Спасибо!.