Asp.net mvc ASP.NET MVC,抛出HttpException vs返回HttpStatusCodeResult?

Asp.net mvc ASP.NET MVC,抛出HttpException vs返回HttpStatusCodeResult?,asp.net-mvc,asp.net-mvc-4,Asp.net Mvc,Asp.net Mvc 4,我正在开发一个RESTful服务,我想为所有不受支持的URL返回400 我的问题是,什么时候我应该选择方法1而不是方法2,反之亦然。 //method 1 public ActionResult Index() { //The url is unsupported throw new HttpException(400, "Bad Request"); } 这个似乎更好 //method 2 public ActionResult Index() { //The url

我正在开发一个RESTful服务,我想为所有不受支持的URL返回400

我的问题是,什么时候我应该选择方法1而不是方法2,反之亦然。

//method 1
public ActionResult Index()
{
    //The url is unsupported
    throw new HttpException(400, "Bad Request");
}
这个似乎更好

//method 2
public ActionResult Index()
{
    //The url is unsupported
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Bad Request");
}

第二个似乎更好,因为它不包含异常抛出,这与第一个例子相比是微不足道的。

在我看来,首先需要考虑是否对不支持的URL提出请求。那么,你认为这是一种特殊情况,还是你认为会发生这种情况?如果您认为这是一个异常情况,那么创建并抛出一个异常(选项1)。如果您希望在不受支持的URL上收到许多请求,则将其视为应用程序的一个功能,并使用方法2

也就是说,如果您希望在不受支持的URL上有太多的请求,那么您需要再次考虑您的客户端的请求。一般来说,我希望抛出一个异常,因为我不希望在不受支持的URL上收到太多请求,如果确实发生了,那么我希望将其作为异常记录并调查原因。

作为一个团队,我们都有这样的思维定势,在某些东西上投入更多的硬件来获得稍微好一点的结果总是一个好的理由。所以我故意忽略了触发.NET异常的微观成本

如果您正在利用遥测框架,那么只返回状态代码只会给您一个“失败的请求”。它不会提供任何有用的信息,使您能够编译或获取有关失败请求的“原因”的任何信息

遥测平台期望并希望您抛出错误,因为错误遥测通常围绕.NET异常,所以如果您不抛出错误,则会给操作带来问题


实际上,我是在这里登陆的,因为我正在为一个项目编写一个分析器和代码修复程序,在这个项目中,人们喜欢编写
try{}catch{return BadRequest(“put_the_reason_here”)}
而且无论是DevOps还是开发团队都没有在ApplicationInsights中看到任何有用的系统遥测功能。

虽然这个问题有点老了,但我想我会给出我的输入,因为我遇到了这个问题

错误是值。这适用于
HttpException
(解除锁定时)以及
httpstatuscodesult
。但是,抛出的异常会创建新的代码路径,这些代码路径对您的同事隐藏,可能是比您的执行上下文更高的一个执行上下文,并且必须提供文档说明这些代码路径将在不通知的情况下传递给他们。然而,值通过其类型告诉您需要知道的一切。您可以在预期的执行路径中使用它们的类型来判断是否发生了错误,以及查找与该错误相关的信息并记录它

我有时使用(稍微扩展的)
异常
,而不将它们放到下一个执行上下文中,以提取David Rodriguez提到的有用的调试信息。没有理由将抛出的异常处理到您上面的执行上下文中,而这些执行上下文实际上并不是异常的,这只适用于代码实际无法处理的事情(
StackOverflowException
,其他致命的系统异常,等等)

在网络应用程序中,例如运行的任何MVC服务,抛出异常的性能损失都是毫无意义的。语义和对可维护性的影响并不重要


网络错误是值,您应该这样处理它们。

我确信这两者之间在语义上肯定有着比简单的异常抛出开销更有意义的区别。@AntP,对于第一个,您希望ASP.NET MVC将拦截此HttpException并返回相应的状态代码—这一行为有朝一日可能会改变。对于第二个,一切都非常明确。您正在准确地告诉在这种情况下应该发生什么-将请求返回给客户。不,恰恰相反。第二种更为稳健。正如我在第一个示例中所说的,您依赖于这样一个事实:一些代码将截获您抛出的异常,分析其类型,并且由于它是一个HttpException,它将提取您设置的StatusCode并将其返回给客户机。对于第二个,您直接且显式地将此状态代码发送到响应。还有什么比您想要的更健壮的呢?第二个不会被异常过滤器捕获。因此,如果您有一个全局异常过滤器,第二个选项将不会记录任何异常。我已经就此事发表了我的意见。如果你愿意,就扔吧。我不会使用第一个代码。但是我尊重你对这个问题的看法。你不认为一个不支持的URL是MVC中的一个特殊情况吗?一个不支持的URL对我来说并不是一个例外情况,因为我把异常和错误之间的界限画为运行时在我的控制之外的东西之间的差别。(由于错误代码和系统故障(如内存不足)引发的异常)以及运行时我可以控制的事情(用户输入不佳)不适当的输入不是一个例外情况,而是一个错误的情况,应该用标准的、可见的代码路径来代替隐藏的抛出的代码路径,因为异常处理增加了复杂性和隐藏的代码路径,而且代价高昂。我同意HuooIDIDAudio——在ASP.NET MVC中,我考虑大多数HTTP错误。毕竟,我之所以为某些响应输入不同的代码,是因为我预测了这样做的必要性。