如果用户无权采取行动,如何隐藏操作链接?

Spo*_*sST 10 asp.net-mvc

@if (Roles.IsUserInRole("Administrators"))
{
  <li>@Html.ActionLink("Create New", "Create")</li>
}
Run Code Online (Sandbox Code Playgroud)

我为用户提供了很多角色,并且可以访问多个角色.

在很多地方改变if语句是非常困难的 - 这是一种仅基于隐藏actionlink的方法Athorize(Roles="Administrator, SomethingElse")吗?

也许有一种方法可以编写自定义帮助程序来检查用户权限并使用它而不是Html.Actionlink?

Spo*_*sST 8

经过一些试验和错误,这里建议的解决方案有效.然而,消化解决方案适用于以前的框架版本.

编辑解决方案:

 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;
    }

}
Run Code Online (Sandbox Code Playgroud)


Dar*_*rov 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在我看来:

@Html.ActionLinkIfInRole("Administrators", "Create New", "Create")
Run Code Online (Sandbox Code Playgroud)