@if (Roles.IsUserInRole("Administrators"))
{
<li>@Html.ActionLink("Create New", "Create")</li>
}
我为用户提供了很多角色,许多操作都可以访问多个角色。
在很多地方改变if语句是非常困难的 - 这是一种仅基于Athorize(Roles="Administrator, SomethingElse")
来隐藏actionlink的方法吗?
也许有办法编写自定义帮助程序来检查用户权限并使用它代替Html.Actionlink?
答案 0 :(得分:8)
经过一些试验和错误后,解决方案建议here有效。但是,以前的框架版本提供了解决方案。
编辑解决方案:
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;
}
}
答案 1 :(得分:7)
我会写一个自定义操作链接助手:
public static class LinkExtensions
{
public static IHtmlString ActionLinkIfInRole(
this HtmlHelper htmlHelper,
string roles,
string linkText,
string action
)
{
if (!Roles.IsUserInRole(roles))
{
return MvcHtmlString.Empty;
}
return htmlHelper.ActionLink(linkText, action);
}
}
然后在我的观点中:
@Html.ActionLinkIfInRole("Administrators", "Create New", "Create")