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

Pat*_*cia 13 asp.net-mvc attributes

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

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

use*_*702 10

至少在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Bar.OnActionExecuting
Foo.OnActionExecuting
Exception thrown: 'System.Exception' in WebApplication1.dll
Foo.OnActionExecuted
Has exception: True
Bar.OnActionExecuted
Has exception: True
Run Code Online (Sandbox Code Playgroud)

测试用例在过滤器中有异常

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

Bar.OnActionExecuting
Foo.OnActionExecuting
Foo.OnActionExecuted
Has exception: False
Exception thrown: 'System.Exception' in WebApplication1.dll
Bar.OnActionExecuted
Has exception: True
Run Code Online (Sandbox Code Playgroud)