我有一个自定义的ViewEngine,我想根据所请求的操作是否有Authorize属性过滤器来修改所使用的母版页。
到目前为止,我只是像这样使用反射:
var method = controllerContext.Controller.GetType().GetMethod(viewName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase);
if (method != null)
{
if (method.GetCustomAttributes(typeof(AuthorizeAttribute), true).Length > 0)
{
masterName = "Admin.master";
}
}但我不太喜欢使用反射来完成重复的任务。我知道我可以在第一次之后使用视图缓存来加快速度,但是我想知道是否有一种更直接的方法来访问ViewEngine的FindView方法中应用于操作的过滤器列表
发布于 2009-11-02 22:38:49
您几乎被限制在使用反射来获取任何属性信息,而不管包括MVC操作方法在内的任何内容。;)
获取此信息的唯一其他技术是通过ControllerDescriptor路径
在您的情况下,您完全可以跳过查找authorize属性,而只是询问用户是否获得授权,并为他们提供所需的母版页。
我以前在自定义视图引擎中动态设置过母版页,性能最好的选项是查看任何可用的HttpContextBase信息。对于一个场景,当我需要使用它们时,我只是传递查询参数或附加在{masterPage}路由参数上。
唯一另一条获取行动信息的途径是ReflectedControllerDescriptor路径。这种方法的问题是它非常冗长,并且需要很多行代码才能完成您所做的事情。
下面是一些代码(我在stackoverflow上找到的!)来进行安全链接修剪。如果母版页在自定义视图引擎中,则此代码还可用于动态设置母版页。这不是你想要的,但可能会帮助其他人在其他地方完成相同的动态主页设置:
public static bool HasActionPermission( this HtmlHelper htmlHelper, string actionName, string controllerName )
{
//if the controller name is empty the ASP.NET convention is:
//"we are linking to a different controller
ControllerBase controllerToLinkTo = string.IsNullOrEmpty(controllerName)
? htmlHelper.ViewContext.Controller
: GetControllerByName(htmlHelper, controllerName);
var controllerContext = new ControllerContext(htmlHelper.ViewContext.RequestContext, controllerToLinkTo);
var controllerDescriptor = new ReflectedControllerDescriptor(controllerToLinkTo.GetType());
var actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
return ActionIsAuthorized(controllerContext, actionDescriptor);
}
private static bool ActionIsAuthorized(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
if (actionDescriptor == null)
return false; // action does not exist so say yes - should we authorise this?!
AuthorizationContext authContext = new AuthorizationContext(controllerContext);
// run each auth filter until on fails
// performance could be improved by some caching
foreach (IAuthorizationFilter authFilter in actionDescriptor.GetFilters().AuthorizationFilters)
{
authFilter.OnAuthorization(authContext);
if (authContext.Result != null)
return false;
}
return true;
}https://stackoverflow.com/questions/886267
复制相似问题