I am trying to log failed requests from my HttpRequestException
.
My server returns error code and additional JSON payload at the response body. I need to access that JSON. How do I read the response body in case of an errored request? I know that the actual response is not null. It's an API and I confirm that it returns JSON payload with 4xx status codes, giving detailed insight about the error.
How do I access it? Here is my code:
using (var httpClient = new HttpClient())
{
try
{
string resultString = await httpClient.GetStringAsync(endpoint);
var result = JsonConvert.DeserializeObject<...>(resultString);
return result;
}
catch (HttpRequestException ex)
{
throw ex;
}
}
I am trying to get data in throw ex
line, but I couldn't find a way.
Exactly as @Frédéric suggested, if you use GetAsync
method you'll get the proper HttpResponseMessage
object which give more information about the response. To get details when error occurs you can desearlize the errors to an Exception
or your custom exception object from Response content like below:
public static Exception CreateExceptionFromResponseErrors(HttpResponseMessage response)
{
var httpErrorObject = response.Content.ReadAsStringAsync().Result;
// Create an anonymous object to use as the template for deserialization:
var anonymousErrorObject =
new { message = "", ModelState = new Dictionary<string, string[]>() };
// Deserialize:
var deserializedErrorObject =
JsonConvert.DeserializeAnonymousType(httpErrorObject, anonymousErrorObject);
// Now wrap into an exception which best fullfills the needs of your application:
var ex = new Exception();
// Sometimes, there may be Model Errors:
if (deserializedErrorObject.ModelState != null)
{
var errors =
deserializedErrorObject.ModelState
.Select(kvp => string.Join(". ", kvp.Value));
for (int i = 0; i < errors.Count(); i++)
{
// Wrap the errors up into the base Exception.Data Dictionary:
ex.Data.Add(i, errors.ElementAt(i));
}
}
// Othertimes, there may not be Model Errors:
else
{
var error =
JsonConvert.DeserializeObject<Dictionary<string, string>>(httpErrorObject);
foreach (var kvp in error)
{
// Wrap the errors up into the base Exception.Data Dictionary:
ex.Data.Add(kvp.Key, kvp.Value);
}
}
return ex;
}
Usage:
using (var client = new HttpClient())
{
var response =
await client.GetAsync("http://localhost:51137/api/Account/Register");
if (!response.IsSuccessStatusCode)
{
// Unwrap the response and throw as an Api Exception:
var ex = CreateExceptionFromResponseErrors(response);
throw ex;
}
}
Here's the source article detailing more about handling the HttpResponseMessage and it's content.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With