Asp.net mvc 4 在ASP.NET Web API中,如果引发异常,如何使HTTP响应语法一致?

Asp.net mvc 4 在ASP.NET Web API中,如果引发异常,如何使HTTP响应语法一致?,asp.net-mvc-4,asp.net-web-api,Asp.net Mvc 4,Asp.net Web Api,我正在使用ASP.NET Web API创建HTTP API。我注意到,如果发生了我没有处理的异常,那么这种行为与我故意抛出HttpResponseException的行为非常不同。这将使客户端难以可靠地处理错误并显示“原因”消息 请考虑此代码: [HttpPost] public void ThisWillThrowAnError() { try { var i = 0; var b = 1 / i; // cause divide by zer

我正在使用ASP.NET Web API创建HTTP API。我注意到,如果发生了我没有处理的异常,那么这种行为与我故意抛出HttpResponseException的行为非常不同。这将使客户端难以可靠地处理错误并显示“原因”消息

请考虑此代码:

[HttpPost]
public void ThisWillThrowAnError()
{
    try
    {
        var i = 0;
        var b = 1 / i; // cause divide by zero exception for testing
    }
    catch (Exception ex)
    {
        HttpResponseMessage message = new HttpResponseMessage();
        message.ReasonPhrase = "Error: " + ex.Message;
        throw new HttpResponseException(message);
    }
}
这将创建一个HTTP头中有错误且响应代码设置为500的响应: 错误:无法处理此请求。试图除以零

实际响应主体为空

但是,如果我删除try/catch块,或者如果发生异常,而我没有手动抛出HttpResponseException,则会得到完全不同的行为。尽管状态代码仍然为500,但标题消息只显示“Internal Server Error”,并且消息以JSON格式编码,如下所示:

{
  "Message": "An error has occurred.",
  "ExceptionMessage": "Attempted to divide by zero.",
  "ExceptionType": "System.DivideByZeroException",
  "StackTrace": " at ProjectName.Controllers (etc....)"
}
我想我更喜欢后者,因为它为调试提供了更多信息,但它取消了定制消息或为问题提供用户可读消息的功能


为什么WebAPI与它处理异常的方式不一致?我自己是否在做什么导致这种不一致?这似乎是相当混乱和困难的工作,可能意味着调用应用程序必须被编码来处理两种不同类型的错误响应:(

创建错误响应时,考虑使用HypReQuestMasAg.CealError Read创建与WebAPI发送的一致的错误响应)。 希望这篇博文能对您有所帮助:

我会使用。消息处理程序是一个接收HTTP请求并返回HTTP响应的类。因此,您基本上可以在一个位置更改响应结构,对成功和失败以及Web Api中的所有请求都有相同的响应。您可以在我的博文中了解到这一点:

我猜在后一种情况下,框架是创建的以自己的方式处理异常,在前一种情况下,您以自己的方式创建异常,因此存在差异。您可以使用
ActionFilter
属性添加一致性,类似于Web API中的异常处理中所述,这一点有点棘手。还有一些错误您无法通过过滤器捕获。t他的
HttpResponseException
是在控制器管道中专门处理的:答案显然只对未来的读者有用,因为您可能已经解决了您的问题。