在HttpContext.Current上发送覆盖响应不是一个好主意?

时间:2014-06-27 22:08:49

标签: c# asp.net asp.net-web-api httpcontext asp.net-web-api2

我有一项服务,人们使用oData来过滤数据。示例字符串类似于$orderby=[SSN]&$top=3。当无法解析字符串时,它会抛出InvalidCastException并抓住它并告诉用户无法解析查询。

这就是问题所在。通过这种方法,我需要对每个控制器操作执行try/catch,这会使代码混乱,我不喜欢它的外观。现在假设您的控制器中有5个动作,并且每个动作都包含相同的try/catch

实施例

public IHttpActionResult Home()
{
    try
    {
        var users = db.GetCollection("users")
        .AsQueryable()
        .AsFilteredObjects(Request.RequestUri.Query); // This line may cause exception
        return Ok(users);
    }
    catch (InvalidCastException)
    {
        return BadRequest(string.Format("Query ({0}) is invalid.", Request.RequestUri.Query));
    }
}

我做了什么

我从控制器中移除try/catch并将其移至AsFilteredObjects内,然后摆弄HttpContext.Current以返回相同的响应。

public static CustomJson AsFilteredObjects(this IQueryable<BsonDocument> documents, string query)
{
    try
    {
        // removed because not really relevent
        return json;
    }
    catch (InvalidCastException)
    {
        // Simulate "return BadRequest()"
        HttpContext.Current.Response.Clear();
        HttpContext.Current.Response.SubStatusCode = (int) HttpStatusCode.BadRequest;
        HttpContext.Current.Response.Output.Write("{\"Message\":\"Query (" + query + ") is invalid.\"}");
        HttpContext.Current.Response.ContentType = "application/json";
        HttpContext.Current.Response.End();
        return null;
    }
}

我的问题

出于某种原因,感觉这是个糟糕的主意。我想知道是否有更优雅的方式这样做?

1 个答案:

答案 0 :(得分:2)

在我看来,您应该使用Web API 2中的全局ExceptionHandler

This link将告诉您Web API中的异常处理,this link应该有助于解释Web API中的全局异常处理。它允许您从所有地方抛出异常并在一个地方捕获/处理它们。

以前,Web API并没有一种简单的方法来处理全局错误。可以通过异常过滤器处理一些未处理的异常,但是有一些异常过滤器无法处理的情况。解决方案是提供新的用户可替换服务IExceptionHandler,以处理未处理的异常。它提供对包含检测到异常的相关信息的异常上下文的访问,特别是HttpRequestMessage,HttpRequestContext,抛出的异常和异常源。

通过以上链接中的示例,在我的项目中,我现在可以抛出各种异常,而不用担心try / catch会被抛出(用我的代码污染我的代码)因为我的全局异常处理程序现在在一个地方配置并处理(几乎)所有可能的异常,所以遍及整个地方的异常处理。并且因为每个规则都有一个&#34;例外&#34; (双关语!),在这种情况下,它是HttpResponseException类型,它不是由全局异常处理程序处理的。