Nat*_*edy 7 c# reflection html-helper asp.net-mvc-3
我正在尝试查看任何可能在MVC 3应用程序中的控制器中修饰操作方法的身份验证属性.我在我自己的HtmlHelper扩展方法中执行此操作,这些方法基本上是ActionLink的包装器(为您提供我在运行时可用的信息的上下文).我有一个基本的解决方案,但重载的方法刚刚爆炸.我知道框架在内部解析了动作方法的URL,但在查看了System.Web.Mvc.LinkExtensions的代码之后,我仍然没有准确地发现它是如何发生的,所以我有点陷入困境解决这个问题.
这是我到目前为止解决相关方法的代码:
private static bool _IsUserAuthorized(HtmlHelper html,
string controllerName, string actionName)
{
controllerName = controllerName ??
html.ViewContext.RouteData.GetRequiredString("controller");
var factory = ControllerBuilder.Current.GetControllerFactory();
var controller = factory.CreateController(
html.ViewContext.RequestContext, controllerName);
Type controllerType = controller.GetType();
var methodInfo = controllerType.GetMethod(actionName,
BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
... check authentication
}
Run Code Online (Sandbox Code Playgroud)
所以我当前的问题是,当一个方法被覆盖时,我得到"模糊匹配发现"异常.我猜我需要处理RouteValues来解析方法的任何参数,这样我才能明确地识别正确的参数.有没有人对如何做到这一点有一些指示?或者,框架是否已经提供了解决所需方法的方法?
非常感谢!
编辑:更新了方法以包含此页面的见解。此最终版本会查看AuthorizationFilters请求的操作方法并检查用户是否有权执行该操作。
所以我深入研究System.Web.Mvc.ControllerActionInvoker并找到了我需要的方法和构造函数。
ControllerDescriptor.FindAction()最终成为关键。下面,我复制了我编写的用于检索所有属性的方法:
private static bool _IsUserAuthorized(HtmlHelper htmlHelper,
string controllerName,
string actionName)
{
ControllerContext controllerContext = null;
// if controllerName is null or empty,
// we'll use the current controller in HtmlHelper.ViewContext.
if (string.IsNullOrEmpty(controllerName))
{
controllerContext = htmlHelper.ViewContext.Controller.ControllerContext;
} else { // use the controller factory to get the requested controller
var factory = ControllerBuilder.Current.GetControllerFactory();
var controller = (ControllerBase)factory.CreateController(
htmlHelper.ViewContext.RequestContext, controllerName);
controllerContext = new ControllerContext(
htmlHelper.ViewContext.RequestContext, controller);
}
var controllerType = controllerContext.Controller.GetType();
var controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
var actionDescriptor = controllerDescriptor.FindAction(
controllerContext, actionName);
if (actionDescriptor == null)
{
return false;
}
var filters = new FilterInfo(
FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor)
);
var authContext = new AuthorizationContext(controllerContext, actionDescriptor);
foreach (IAuthorizationFilter authFilter in filters.AuthorizationFilters)
{
authFilter.OnAuthorization(authContext);
if (authContext.Result != null)
{
return false;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1868 次 |
| 最近记录: |