Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 解释MVC Authorize属性如何执行类似AOP的操作_C#_.net_Asp.net Mvc_Aop_Postsharp - Fatal编程技术网

C# 解释MVC Authorize属性如何执行类似AOP的操作

C# 解释MVC Authorize属性如何执行类似AOP的操作,c#,.net,asp.net-mvc,aop,postsharp,C#,.net,Asp.net Mvc,Aop,Postsharp,我一直在试图弄清楚这在低层次上是如何工作的: [Authorize] public ActionResult Index() { return View(); } 基本上,上面的代码片段似乎截取对Index方法的调用,执行授权检查,如果未授权,则抛出和异常。异常阻止调用Index方法中的代码 这看起来很像AOP,在C#中不容易做到。如果我要实现我自己的扩展System.Attribute类,我就不会有任何接口连接到我的属性所修饰的方法的调用前或调用后。那么MVC Authorize属性

我一直在试图弄清楚这在低层次上是如何工作的:

[Authorize]
public ActionResult Index()
{
    return View();
}
基本上,上面的代码片段似乎截取对Index方法的调用,执行授权检查,如果未授权,则抛出和异常。异常阻止调用Index方法中的代码

这看起来很像AOP,在C#中不容易做到。如果我要实现我自己的扩展System.Attribute类,我就不会有任何接口连接到我的属性所修饰的方法的调用前或调用后。那么MVC Authorize属性是如何实现的,我自己又是如何实现的呢

PostSharp是一个库,它使用IL编织完成同样的事情。基本上,在编译时,PostSharp会扫描程序集以查找用某些属性修饰的方法,然后重新编写代码以用其他方法调用包装方法调用

MVC框架是否也在编译时执行某种IL编织?我可以自己表演吗?或者是否有其他技术可以应用相同的AOP原则而不需要复杂的IL编织


我试图找到关于IL-Weaving的信息,但我找到的都是关于PostSharp的文章。我宁愿远离PostSharp,因为许可证问题,但我只想知道他们是如何为我作为一名开发人员的成长做这件事的。这很吸引人

理解它的最简单方法是查看源代码

一个基本的解释是mvc控制器并不是简单地像instance.method那样被调用(在这种情况下,您需要postsharp使属性以同样的方式工作)

有一个
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); 
首先执行继承
iaauthorizationfilter
的所有筛选器
(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);
}
AuthorizationContext authContext=InvokeAuthorizationFilters(controllerContext,filterInfo.AuthorizationFilters,actionDescriptor);
//如果授权未成功,则authContext.Result具有值
if(authContext.Result!=null)
{
//auth过滤器发出信号,我们应该让它短路请求
InvokeActionResult(controllerContext,authContext.Result);
}
其他的
{
if(controllerContext.Controller.ValidateRequest)
{
ValidateRequest(controllerContext);
}
IDictionary parameters=GetParameterValues(controllerContext、actionDescriptor);
//在此处使用过滤器调用操作
ActionExecuteContext postActionContext=InvokeActionMethodWithFilters(controllerContext,filterInfo.ActionFilters,actionDescriptor,参数);
InvokeActionResultWithFilters(controllerContext、filterInfo.ResultFilters、postActionContext.Result);
}

如果您还没有这样做,请获取MVC源代码。如果我记得的话,没有什么比编织更复杂的了;框架只是在调用控制器方法之前执行操作方法属性。请求->路由->控制器选择->获取相关操作方法->执行相关属性->执行操作方法.Nice。它是虚拟的,所以如果我们想添加其他类型的与授权无关的基于属性的过滤器(比如日志记录),我们可以扩展它。因此,如果没有PostSharp或滚动我们自己的IL Weaver,就无法像往常一样自动神奇地向任何随机类添加类似AOP的属性并调用方法。这是有道理的。您不必重写它来添加其他过滤器:我想如果我想让自定义属性约束我的非控制器方法(如filter),这将非常困难。。