ASP.NET MVC中的自定义授权过滤器

时间:2013-04-15 23:30:28

标签: c# asp.net-mvc asp.net-mvc-4

我有一个绑定到站点地图的telerik mvc菜单。所有链接都已正确设置,并且成功绑定。但是在post方法中,如果使用View(model)将模型回发到视图以查找无效模型,则会出现以下错误。它适用于PRG模式,即,如果我重定向到查看。

  

INFO [System.NullReferenceException:对象引用未设置为   对象的实例。在   Telerik.Web.Mvc.Infrastructure.Implementation.ControllerAuthorization.IsAccessibleToUser(的RequestContext   requestContext,String controllerName,String actionName,   RouteValueDictionary routeValues)在f:\ 109 \ Griffin \ Trunk中   完全\来源\来源\ Telerik.Web.Mvc \基础设施\执行\ ControllerAuthorization.cs:行   75点   Telerik.Web.Mvc.Infrastructure.Implementation.NavigationItemAuthorization.IsAccessibleToUser(的RequestContext   f:\ 109 \ Griffin \ Trunk中的requestContext,INAVigatable navigationItem)   完全\来源\来源\ Telerik.Web.Mvc \基础设施\执行\ NavigationItemAuthorization.cs:行   38

通过调试代码,我发现它在内部调用System.Web.MVC类来检索节点的授权信息。下面是为无效模型返回null的行,否则如果它是重定向或正常的GET操作,它将正常工作。

ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
if (actionDescriptor == null) 
{
     return null; **//it returns null for View(model)**
}
return new AuthorizationContext(controllerContext, actionDescriptor) { Controller = { ControllerContext = controllerContext } };

System.Web.Mvc中的FindAction方法。从这种方法调用RunSelectionFilters,为正常情况和异常情况产生不同的输出。

 public MethodInfo FindActionMethod(ControllerContext controllerContext, string actionName)
        {
            List<MethodInfo> matchingAliasedMethods = this.GetMatchingAliasedMethods(controllerContext, actionName);
            matchingAliasedMethods.AddRange(this.NonAliasedMethods[actionName]);
            List<MethodInfo> ambiguousMethods = RunSelectionFilters(controllerContext, matchingAliasedMethods);
            switch (ambiguousMethods.Count)
            {
                case 0:
                    return null;

                case 1:
                    return ambiguousMethods[0];
            }
            throw this.CreateAmbiguousMatchException(ambiguousMethods, actionName);
        }

对于正常操作,RunSelectionFilters方法返回list2,对于异常情况,返回list

private static List<MethodInfo> RunSelectionFilters(ControllerContext controllerContext, List<MethodInfo> methodInfos)
        {
            List<MethodInfo> list = new List<MethodInfo>();
            List<MethodInfo> list2 = new List<MethodInfo>();
            using (List<MethodInfo>.Enumerator enumerator = methodInfos.GetEnumerator())
            {
                Func<ActionMethodSelectorAttribute, bool> predicate = null;
                MethodInfo methodInfo;
                while (enumerator.MoveNext())
                {
                    methodInfo = enumerator.Current;
                    ICollection<ActionMethodSelectorAttribute> actionMethodSelectorAttributes = ReflectedAttributeCache.GetActionMethodSelectorAttributes(methodInfo);
                    if (actionMethodSelectorAttributes.Count == 0)
                    {
                        list2.Add(methodInfo);
                    }
                    else
                    {
                        if (predicate == null)
                        {
                            predicate = attr => attr.IsValidForRequest(controllerContext, methodInfo);
                        }
                        if (actionMethodSelectorAttributes.All<ActionMethodSelectorAttribute>(predicate))
                        {
                            list.Add(methodInfo);
                        }
                    }
                }
            }
            if (list.Count <= 0)
            {
                return list2;
            }
            return list;
        }

以下是自定义授权属性。此属性应用于BaseController。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class AppActionAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
    {       

        protected virtual bool AuthorizeCore(HttpContextBase httpContext)
        {
           return DBService.IsAuthorized(httpContext.RequestContext().RouteData.Values);
        }

        public virtual void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            if (OutputCacheAttribute.IsChildActionCacheActive(filterContext))
            {
                throw new InvalidOperationException("AuthorizeAttribute cannot be used within a child action caching block.");
            }

            if (this.AuthorizeCore(filterContext.HttpContext))
            {
                HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
                cache.SetProxyMaxAge(new TimeSpan(0L));
                cache.AddValidationCallback(new HttpCacheValidateHandler(this.CacheValidateHandler), null);
            }
            else
            {
                this.HandleUnauthorizedRequest(filterContext);
            }
        }

        private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
        {
            validationStatus = this.OnCacheAuthorization(new HttpContextWrapper(context));
        }

        protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }

            if (!this.AuthorizeCore(httpContext))
            {
                return HttpValidationStatus.IgnoreThisRequest;
            }
            return HttpValidationStatus.Valid;
        }
    }

0 个答案:

没有答案