How to handle Http Status code when making use of

2019-08-29 02:14发布

问题:

I have a JavaScript client which makes Ajax call to a .net service (Lets call it First service). First service then makes call to another .net Controller (Call it Second Service). In this controller, I am throwing some exception. On the first line I am saying:

//Code from Second Service

[HttpPost]
public HttpResponseMessage Results(ParamsModel data)
{
    throw new Exception("Exception for testing purpose");

}

//Code from First Service

    [HttpPost]
    public ActionResult Results(ParamsModel data)
    {

        var client = new HttpClient();
        var task = client.PostAsJsonAsync(urlTemplate, data);
        var result = task.Result.Content.ReadAsStringAsync().Result;

        return Content(result, "application/json");

    }

Problem: Though the Second Service is throwing error & returning 500 status code, The first servcie returns 200 status code to the JavaScript client. I am also not able to read the satus code returned by Second service as I only get string output.

Please suggest. I want to return 500 status code when there is an error.

回答1:

You can implement error handling as follows in the HttpClient.

if (!task.Result.IsSuccessStatusCode)
{
   if (task.Result.StatusCode == HttpStatusCode.InternalServerError)
   {
      return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "An error has occured.");
   }
   else
   {
      // Check for other status codes and handle the responses
   }
}
else
{
  // Success status code. Return success response.
}

Hope this helps.



回答2:

Why can't you do an asynchronous action method?

[HttpPost]
public async Task<ActionResult> Results(ParamsModel data)
{
    try
    {
        var client = new HttpClient();
        var response = await client.PostAsJsonAsync(urlTemplate, data);
        var json = await response.Content.ReadAsStringAsync()
        return Content(result, "application/json");
    }
    catch(WebException ex)
    {
        //do note that the Response property might be null due to
        // connection issues etc. You have to handle that by yourself.
        var remoteErrorCode = ((HttpWebResponse)ex.Response).StatusCode;
        Request.CreateErrorResponse(remoteErrorCode, "An error just happened");
    }
}

But the thing is, with the layout of the first method it doesn't matter how you handle exceptions in the second one, as the first will always return "Internal Server Error".

To make it useful, you should typically return different error codes in the first method too.



回答3:

You can return a HttpResponseException like this:

[HttpPost]
public ActionResult Results(ParamsModel data)
{
    try
    {   
        var client = new HttpClient();
        var task = client.PostAsJsonAsync(urlTemplate, data);
        var result = task.Result.Content.ReadAsStringAsync().Result;

        return Content(result, "application/json");
    }
    catch (HttpResponseException ex)
    {
            return new HttpStatusCodeResult(ex.Response.StatusCode);
    }
}

You will need to throw the right exception from your WebAPI controller:

[HttpPost]
public HttpResponseMessage Results(ParamsModel data)
{
    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
}

There are several status codes that can be thrown:

https://msdn.microsoft.com/en-us/library/system.net.httpstatuscode.aspx