我一直试图弄清楚它是如何在低级别上运作的:
[Authorize]
public ActionResult Index()
{
return View();
}
基本上,上面的代码片段似乎拦截了对Index方法的调用,执行了授权检查,并且如果未经授权则抛出异常。该异常可防止调用Index方法中的代码。
这看起来很像AOP,并不是C#中容易做到的事情。如果我要实现我自己的扩展System.Attribute的类,我将没有任何接口可以挂接到我的属性修饰的方法的前或后调用。那么MVC Authorize属性如何做呢,我怎么能自己做呢?
PostSharp是一个使用IL Weaving完成同样事情的库。基本上,在编译时,PostSharp会扫描程序集以查找使用某些属性修饰的方法,然后重新编写代码以使用其他方法调用包装方法调用。
MVC框架是否也在编译时执行某种IL编织?我有可能进行自己的IL编织吗?或者是否有其他技术可以应用相同的AOP原则而无需复杂的IL编织?
我试图找到关于IL编织的信息,但我找到的只是关于PostSharp的文章。由于许可麻烦,我宁愿远离PostSharp,而且,我只是想知道他们为我自己作为开发人员的成长做了多少。这真是令人着迷。
答案 0 :(得分:6)
了解它的最简单方法是查看源代码。
一个基本的解释是mvc控制器不是简单地调用像instance.method(在这种情况下你需要postharp来使属性以相同的方式工作)
有一个ControllerActionInvoker
它有方法
public virtual bool InvokeAction(ControllerContext controllerContext, string actionName)
{
...
// get all the filters (all that inherit FilterAttribute), inlcuding the authorize attribute
FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);
首先,所有继承IAuthorizationFilter
的过滤器都会被执行(Authorize, ValidateAntiForgeryToken)
,如果auth成功完成其余的
AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
//authContext.Result has value if authorization didn't succeed
if (authContext.Result != null)
{
// the auth filter signaled that we should let it short-circuit the request
InvokeActionResult(controllerContext, authContext.Result);
}
else
{
if (controllerContext.Controller.ValidateRequest)
{
ValidateRequest(controllerContext);
}
IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
//invoke the action with filters here
ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);
InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
}