如何隐藏动作链接,如果用户有任何行动的权利? [英] How to hide action link if user has no rights to action?
问题描述
@if (Roles.IsUserInRole("Administrators"))
{
<li>@Html.ActionLink("Create New", "Create")</li>
}
我bounch为用户和许多行动的角色是入店对多个角色。
I have bounch of roles for users and many actions is accesible for more than one role.
这将是非常难以改变,如果在很多地方说法 - 是藏在哪里ActionLink的仅基于办法Athorize(角色=管理员,SomethingElse)
?
It will be very hard to change that if statement in many places - is where a way to hide actionlink based only on Athorize(Roles="Administrator, SomethingElse")
?
也许有编写自定义的助手的方式,检查用户premisions并使用它,而不是Html.Actionlink的?
Maybe there is a way to write custom helper that checks user premisions and using it instead of Html.Actionlink?
推荐答案
一些试验和错误后,该解决方案建议<一href=\"http://stackoverflow.com/questions/5477019/how-to-override-the-actionlink-behavior/5477092#5477092\">here作品。然而sugested解决方案是previous框架版本。
After some trial and error, the solution suggested here works. However sugested solution was for previous framework version.
编辑解决方案:
public static class AuthorizeActionLinkExtention
{
public static MvcHtmlString AuthorizeActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes)
{
if (HasActionPermission(helper, actionName, controllerName))
return helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
return MvcHtmlString.Empty;
}
public static MvcHtmlString AuthorizeActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName)
{
if (HasActionPermission(helper, actionName, controllerName))
return helper.ActionLink(linkText, actionName, controllerName);
return MvcHtmlString.Empty;
}
public static MvcHtmlString AuthorizeActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
{
if (HasActionPermission(helper, actionName, controllerName))
return helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);
return MvcHtmlString.Empty;
}
static bool HasActionPermission(this HtmlHelper htmlHelper, string actionName, string controllerName)
{
ControllerBase controllerToLinkTo = string.IsNullOrEmpty(controllerName)
? htmlHelper.ViewContext.Controller
: GetControllerByName(htmlHelper, controllerName);
ControllerContext controllerContext = new ControllerContext(htmlHelper.ViewContext.RequestContext, controllerToLinkTo);
ReflectedControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerToLinkTo.GetType());
ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
return ActionIsAuthorized(controllerContext, actionDescriptor);
}
static bool ActionIsAuthorized(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
if (actionDescriptor == null)
return false;
AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor);
foreach (Filter authFilter in FilterProviders.Providers.GetFilters(authContext, actionDescriptor))
{
if (authFilter.Instance is System.Web.Mvc.AuthorizeAttribute)
{
((IAuthorizationFilter)authFilter.Instance).OnAuthorization(authContext);
if (authContext.Result != null)
return false;
}
}
return true;
}
static ControllerBase GetControllerByName(HtmlHelper helper, string controllerName)
{
IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
IController controller = factory.CreateController(helper.ViewContext.RequestContext, controllerName);
if (controller == null)
{
throw new InvalidOperationException(
string.Format(
CultureInfo.CurrentUICulture,
"Controller factory {0} controller {1} returned null",
factory.GetType(),
controllerName));
}
return (ControllerBase)controller;
}
}
这篇关于如何隐藏动作链接,如果用户有任何行动的权利?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!