Getting response body on failed request with HttpRequestException

Use GetAsync instead of GetStringAsync. GetAsync will not throw an exception and will allow you to access response content, status code and any other header you may require.

See this page for more.


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.