属性的OnActionExecuted方法是否始终执行?

时间:2009-10-30 14:26:27

标签: asp.net-mvc attributes

我搜索过高低,我似乎无法找到一个直接的答案。

如果我有自定义属性/过滤器,是否始终会调用OnActionExecuted方法?即使抛出异常?

1 个答案:

答案 0 :(得分:6)

至少在MVC 5中,@ tvanfosson的回答不再正确。这也适用于早期版本。

OnActionExecuted始终被调用,并且可以通过filterContext.Exception访问引发的异常。

在操作中具有异常的测试用例:

public class HomeController
    : Controller
{
    public ActionResult Index()
    {
        throw new Exception("Index");
    }
}

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new Foo());
        filters.Add(new Bar());
    }
}

public class Foo
    : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine($"{nameof(Foo)}.{nameof(OnActionExecuting)}");
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine($"{nameof(Foo)}.{nameof(OnActionExecuted)}");
        Debug.WriteLine($"Has exception: {filterContext.Exception != null}");
        base.OnActionExecuted(filterContext);
    }
}

public class Bar
    : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine($"{nameof(Bar)}.{nameof(OnActionExecuting)}");
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine($"{nameof(Bar)}.{nameof(OnActionExecuted)}");
        Debug.WriteLine($"Has exception: {filterContext.Exception != null}");
        base.OnActionExecuted(filterContext);
    }
}

输出:

Bar.OnActionExecuting
Foo.OnActionExecuting
Exception thrown: 'System.Exception' in WebApplication1.dll
Foo.OnActionExecuted
Has exception: True
Bar.OnActionExecuted
Has exception: True

过滤器中带例外的测试用例

public class HomeController
    : Controller
{
    public ActionResult Index()
    {
        return new HttpStatusCodeResult(200);
    }
}

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new Foo());
        filters.Add(new Bar());
    }
}

public class Foo
    : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine($"{nameof(Foo)}.{nameof(OnActionExecuting)}");
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine($"{nameof(Foo)}.{nameof(OnActionExecuted)}");
        Debug.WriteLine($"Has exception: {filterContext.Exception != null}");
        throw new Exception("Foo");
        base.OnActionExecuted(filterContext);
    }
}

public class Bar
    : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine($"{nameof(Bar)}.{nameof(OnActionExecuting)}");
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine($"{nameof(Bar)}.{nameof(OnActionExecuted)}");
        Debug.WriteLine($"Has exception: {filterContext.Exception != null}");
        base.OnActionExecuted(filterContext);
    }
}

输出:

Bar.OnActionExecuting
Foo.OnActionExecuting
Foo.OnActionExecuted
Has exception: False
Exception thrown: 'System.Exception' in WebApplication1.dll
Bar.OnActionExecuted
Has exception: True