MVC 3自定义授权属性isDefined始终返回true
问题描述:
我已经定义了一个自定义的授权属性,它自动应用于解决方案中的所有操作。 在其OnAuthorize方法中,我使用IsDefined方法来查找是否定义了另一个属性,但似乎总是返回false。MVC 3自定义授权属性isDefined始终返回true
编辑:AuthorizeAttr属性在Global.asax中的RegisterGlobalFilters函数中设置,Anon属性直接标记在不需要授权的操作之上。
这里是我的代码:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class Anon : Attribute { }
public class Role : Attribute
{
public int Id;
public Role(int id)
{
Id = id;
}
}
public class AuthorizeAttr : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (!(filterContext.ActionDescriptor.IsDefined(typeof(Anon), false)) || !(filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(Anon), false)))
{
Procurement.User u = MvcApplication.GetCurrentUser(filterContext.HttpContext);
if (u == null || !u.enabled)
filterContext.Result = new RedirectResult("/Session/Login?msg=You must log in to use this site.&ReturnUrl=" + filterContext.RequestContext.HttpContext.Request.RawUrl);
if (filterContext.ActionDescriptor.IsDefined(typeof(Role), false))
{
object[] criterias = filterContext.ActionDescriptor.GetCustomAttributes(typeof(Role), false);
bool authorized = true;
for (int x = 0; x < criterias.Length; x++)
{
if (((Role)criterias[x]).Id > u.roleId)
{
authorized = false;
break;
}
}
if (!authorized)
{
ContentResult C = new ContentResult();
C.Content = "<h1><b>The resource is unavailable!</b></h1>";
filterContext.Result = C;
}
}
}
}
}
答
布尔代数的
isDefinedOnAction || isDefinedOnController
的否定是:
!isDefinedOnAction && !isDefinedOnController
所以你可能要一个&&
条件:
public override void OnAuthorization(AuthorizationContext filterContext)
{
var isDefinedOnAction = filterContext.ActionDescriptor.IsDefined(typeof(Anon), false);
var isDefinedOnController = filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(Anon), false);
if (!isDefinedOnAction && !isDefinedOnController)
{
... the Anon attribute is not present neither on an action nor on a controller
=> perform your authorization here
}
}
,或者如果你想||
:
public override void OnAuthorization(AuthorizationContext filterContext)
{
var isDefinedOnAction = filterContext.ActionDescriptor.IsDefined(typeof(Anon), false);
var isDefinedOnController = filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(Anon), false);
if (isDefinedOnAction || isDefinedOnController)
{
... the attribute is present on either a controller or an action
=> do nothing here
}
else
{
... perform your authorization here
}
}
显然,第一种是更具可读性。
啊! Ofcource! 由于我否定了结果,它正在检查它是否不存在,并且只有其中一个没有该属性让if语句中的代码得到执行。 对不起,发布一个简单的逻辑问题,然后求助! –
说得太快了,由于某种原因,它仍然不起作用! –
@Mats Edvinsson,我测试了代码,它工作正常。 if条件之前的'isDefinedOnAction'和'isDefinedOnController'变量的值是什么?他们都是假的吗?你用'[Anon]'属性装饰了一个控制器还是一个动作? –