向AuthorizeAttribute构造函数添加参数会导致MvcSiteMapProvider失败?

时间:2012-10-19 21:47:31

标签: asp.net-mvc mvcsitemapprovider

我一直在使用基于授权属性的MvcSiteMapProvider,直到我们引入了一个派生自AuthorizeAttribute的新类。主要区别在于它的构造函数签名:

public MyAuthorizeAttribute(param RoleCode[] roles) {
    Roles = string.join(",", roles.Select(r => r.ToString());
}

并且...... MvcSiteMapProvider显示意外结果:只有MyAuthorizeAttribute标记的操作变得不可见。我通过禁用这个构造函数检查了一切 - 一切都像在向构造函数添加参数之前一样。此外 - 它不是params特定的 - 任何参数(事件int)都会导致这种行为。

据我所知,从MvcSiteMapProvider源代码中,它会发出一些代码来模拟授权属性 - 但看起来不可能保存外部代码生成的程序集。我知道有一个解决方法 - 使用某种可枚举的属性,但你有任何建议如何使它与构造函数参数一起工作?你知道为什么MvcSiteMapProvider会这样吗?

1 个答案:

答案 0 :(得分:0)

因此,在花了一些时间进行调试之后,我意识到了答案:动态代理

问题是在MVC框架内执行请求期间,没有简单的方法可以找出从AuthorizeAttribute派生的类如何执行其工作。如果访问检查失败,一些可能会抛出异常,一些 - 返回401状态代码,一些重定向到登录页面,依此类推。

但是MvcSiteMapProvides就是这么做的!它使用以下解决方法:

  • 如果课程为AuthorizeAttribute
    • 创建一个InternalAuthorize类的实例,这非常简单。
    • 复制那里的所有属性和
    • 调用返回布尔值的AuthorizeCore方法。
  • 否则
    • 生成从属性类型派生的代理类
    • 创建实例, ///<<这里我们得到一个例外
    • 复制那里的所有属性和
    • 调用返回布尔值的AuthorizeCore方法。

很明显,制作代理并不是一件容易的事,因为代理知道你的构造函数参数。当然,抛出关于默认构造函数缺失的异常,但它会被空catch子句使用。这真的很难过 - 至少一个调试跟踪可以节省我几个小时。

最后答案是:

  • 显然你应该使用无参数属性构造函数(为什么哦为什么在任何地方都没有提到?)
  • 制作自定义acl提供程序:实现IAclModule接口,释放您对自己的授权属性的了解。