在ASP.NET MVC 5中全局使用的过滤器的执行顺序是什么?

问题描述 投票:0回答:1

在asp.net mvc 5中,如果全局添加了以下自定义过滤器(授权,异常),则指定执行顺序

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CPExceptionHandler());
        filters.Add(new LogonAuthorizeAttribute());            
    }

我尝试从链接msdn全局了解过滤器的执行顺序,但无法掌握信息。请帮助我澄清一下,全局过滤器的执行顺序是什么,如授权,异常等,?

asp.net-mvc filter global execution
1个回答
0
投票

在MVC中,过滤器执行的顺序将始终如一

1.授权过滤器 2.动作过滤器 3.响应过滤器 4.例外过滤器

即使在全球范围内添加,也同样适用。

下面是MVC中代码的实现

 if (actionDescriptor != null)
            {
                FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
                Action continuation = null;

                BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState)
                {
                    try
                    {
                        AuthenticationContext authenticationContext = InvokeAuthenticationFilters(controllerContext,
                            filterInfo.AuthenticationFilters, actionDescriptor);
                        if (authenticationContext.Result != null)
                        {
                            // An authentication filter signaled that we should short-circuit the request. Let all
                            // authentication filters contribute to an action result (to combine authentication
                            // challenges). Then, run this action result.
                            AuthenticationChallengeContext challengeContext =
                                InvokeAuthenticationFiltersChallenge(controllerContext,
                                filterInfo.AuthenticationFilters, actionDescriptor, authenticationContext.Result);
                            continuation = () => InvokeActionResult(controllerContext,
                                challengeContext.Result ?? authenticationContext.Result);
                        }
                        else
                        {
                            AuthorizationContext authorizationContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
                            if (authorizationContext.Result != null)
                            {
                                // An authorization filter signaled that we should short-circuit the request. Let all
                                // authentication filters contribute to an action result (to combine authentication
                                // challenges). Then, run this action result.
                                AuthenticationChallengeContext challengeContext =
                                    InvokeAuthenticationFiltersChallenge(controllerContext,
                                    filterInfo.AuthenticationFilters, actionDescriptor, authorizationContext.Result);
                                continuation = () => InvokeActionResult(controllerContext,
                                    challengeContext.Result ?? authorizationContext.Result);
                            }
                            else
                            {
                                if (controllerContext.Controller.ValidateRequest)
                                {
                                    ValidateRequest(controllerContext);
                                }

                                IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
                                IAsyncResult asyncResult = BeginInvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters, asyncCallback, asyncState);
                                continuation = () =>
                                {
                                    ActionExecutedContext postActionContext = EndInvokeActionMethodWithFilters(asyncResult);
                                    // The action succeeded. Let all authentication filters contribute to an action
                                    // result (to combine authentication challenges; some authentication filters need
                                    // to do negotiation even on a successful result). Then, run this action result.
                                    AuthenticationChallengeContext challengeContext =
                                        InvokeAuthenticationFiltersChallenge(controllerContext,
                                        filterInfo.AuthenticationFilters, actionDescriptor,
                                        postActionContext.Result);
                                    InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters,
                                        challengeContext.Result ?? postActionContext.Result);
                                };
                                return asyncResult;
                            }
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
                        // the filters don't see this as an error.
                        throw;
                    }
                    catch (Exception ex)
                    {
                        // something blew up, so execute the exception filters
                        ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
                        if (!exceptionContext.ExceptionHandled)
                        {
                            throw;
                        }

                        continuation = () => InvokeActionResult(controllerContext, exceptionContext.Result);
                    }

                    return BeginInvokeAction_MakeSynchronousAsyncResult(asyncCallback, asyncState);
                };

它将始终执行

 InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);

然后

 InvokeAuthenticationFiltersChallenge(controllerContext,
                                    filterInfo.AuthenticationFilters, actionDescriptor, authorizationContext.Result);

然后

ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);

只有在多次使用相同类型的过滤器时才需要订单

© www.soinside.com 2019 - 2024. All rights reserved.