简体   繁体   中英

Reading response of non-successful HTTP requests done via System.Net.Http.HttpClient (ASP.NET MVC)

I'm working on an ASP.NET webapp made of two modules:

  • An "API" module, offering web service endpoints
  • An "UX" module, calling those endpoints

One of the endpoints in the API module looks like this when simplified:

public class ReportingApiController: System.Web.Mvc.Controller
{
    [HttpPost]
    public async Task<ActionResult> Upload()
    {
        [...]
        return new HttpStatusCodeResult(540, "Failure parsing the file");
    }
}

The UX module calls that endpoint with code that looks like this:

public class ReportingController : System.Web.Mvc.Controller
{
    private async Task Foo()
    {
        var requestContent = [...]

        HttpResponseMessage httpResponse = await httpClient.PostAsync("api/ReportingApi/Upload", requestContent); // `httpClient` is a System.Net.Http.HttpClient

        // How to read the response? Both the HTTP status code returned (540 in the example), and the corresponding message.
    }
}

I have noticed that the PostAsync() call throws an exception in the above example, because HTTP status codes 5XX are not successful. Using a try/catch is ok, as long as I can still read the response code & message. Which hasn't been the case in my tests (I don't see that info in the exception, and httpResponse is null inside the catch clause).

In my preferred scenario, I would like to avoid a try/catch , simply have the PostAsync() call complete normally, and read the code & message in the httpResponse variable.

What do you recommend?

catch the WebException, it will return the original response. Here an example using String Builder to output headers and body from an HttpWebResponse.

    catch (WebException e)
    {
        using (WebResponse response = e.Response)
        {
            HttpWebResponse httpResponse = (HttpWebResponse)response;
            var stringBuilder = new StringBuilder();
            stringBuilder.AppendLine($"Returned Status Code: {httpResponse.StatusCode.ToString()}");
            using (Stream data = httpResponse.GetResponseStream())
            {
                for (var i = 0; i < httpResponse.Headers.Count; ++i)
                {
                    stringBuilder.AppendLine($"{httpResponse.Headers.Keys[i]}: {httpResponse.Headers[i]}");
                }

                using (var reader = new StreamReader(data))
                {
                    string text = reader.ReadToEnd();
                    stringBuilder.AppendLine($"Body: {text}");
                }
            }
            // do whatever
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM