Как обрабатывать код состояния Http при использовании ReadAsStringAsync()

У меня есть клиент JavaScript, который вызывает Ajax-вызов службы .net (давайте назовем ее первой службой). Затем первая служба вызывает другой контроллер .net (назовем ее второй службой). В этом контроллере я выбрасываю какое-то исключение. В первой строке я говорю:

//Код из второго сервиса

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

}

//Код из первого сервиса

    [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");

    }

Проблема: хотя вторая служба выдает ошибку и возвращает код состояния 500, первая служба возвращает код состояния 200 клиенту JavaScript. Я также не могу прочитать код состояния, возвращаемый службой Second, поскольку я получаю только строковый вывод.

Пожалуйста, предложите. Я хочу вернуть код состояния 500 при возникновении ошибки.


person SharpCoder    schedule 16.02.2015    source источник
comment
попробуйте вернуть Request.CreateErrorResponse(HttpStatusCode.Ok, только что произошла ошибка);   -  person Frebin Francis    schedule 16.02.2015
comment
почему вам нужно вернуть код состояния 200, когда происходит ошибка? 200 — результат успеха.   -  person Frebin Francis    schedule 16.02.2015
comment
@FrebinFrancis: мои извинения; Я хочу вернуть код состояния 500 при ошибке. Я обновил вопрос.   -  person SharpCoder    schedule 16.02.2015
comment
вы можете проверить свойство task.StatusCode для проверки кода состояния, возвращаемого запросом API.   -  person Frebin Francis    schedule 16.02.2015
comment
поэтому вы должны использовать return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, Только что произошла ошибка) из второй службы.   -  person Frebin Francis    schedule 16.02.2015


Ответы (3)


Вы можете реализовать обработку ошибок в 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.
}

Надеюсь это поможет.

person Parthasarathy    schedule 16.02.2015

Почему вы не можете использовать метод асинхронного действия?

[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");
    }
}

Но дело в том, что при макете первого метода не имеет значения, как вы обрабатываете исключения во втором, так как первый всегда будет возвращать «Внутреннюю ошибку сервера».

Чтобы сделать его полезным, вы обычно должны возвращать разные коды ошибок и в первом методе.

person jgauffin    schedule 16.02.2015

Вы можете вернуть HttpResponseException следующим образом:

[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);
    }
}

Вам нужно будет создать правильное исключение из вашего контроллера WebAPI:

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

Есть несколько кодов состояния, которые можно выдать:

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

person nik0lai    schedule 16.02.2015