当Action Filter创建响应时,不会调用ASP.NET Web API异常过滤器

时间:2014-05-23 16:57:41

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

使用Web API,我有一个异常过滤器,它应该使用来自某些异常的数据来编写自定义有效负载。这很好。

但是,我还使用了一个动作过滤器,它应该在响应消息中添加一些HTTP标头。当没有抛出异常时,这很好。

但是,当抛出异常时,我的动作过滤器会被赋予NULL响应(HttpActionExecuted.Response),因此无法添加其标题。我已尝试通过在添加标头之前创建新的ResponseMessage来解决此问题,如果响应为NULL。但是当我在动作过滤器中创建一个新的ResponseMessage时,我的异常过滤器不再被调用。

我猜Web API模型在某种程度上表示如果存在响应消息则不会抛出异常。有关如何使用异常过滤器的任何想法,同时仍然有一个动作过滤器添加HTTP标头?

我的异常过滤器:

public class ExceptionStatusFilter : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        if (!(context.Exception is CertainException))
        {
            return;
        }

        var exception = context.Exception as CertainException;

        var error = new DefaultErrorContainer
        {
            Error = new Error
            {
                Description = exception.Message,
                ErrorCode = exception.ErrorCode,
                ErrorThirdParty = exception.ThirdPartyErrorCode
            }
        };

        context.Response = context.Request.CreateResponse(HttpStatusCode.InternalServerError, error);
    }
}

动作过滤器:

public class ProfilingActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext context)
    {
        var header = "foo";

        if (context.Response == null)
        {
            context.Response = new HttpResponseMessage();
        }

        context.Response.Headers.Add("X-SOME-HEADER", header);
    }
}

1 个答案:

答案 0 :(得分:0)

通过此SO link,您可以了解调用Action过滤器的顺序。

异常过滤器是最后一个被调用的过滤器,因此如果您在执行此过滤器之前生成响应或处理异常,则异常过滤器将假定不会抛出任何异常并且它不会执行。

我的建议是异常,创建响应并将标题分别附加到此异常响应。

link也可以提供帮助。

    public override void OnException(HttpActionExecutedContext context)
        {
            if (context.Exception is NotImplementedException)
            {
                context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
                // Append Header here.
                context.Response.Headers.Add("X-SOME-HEADER", header);
            }
        }