本文介绍了如何重写ActionLink的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我想通过ActionLink的方法将一些安全添加到我的网站。如果用户具有足够的权限访问动作/控制器则ActionLink的应该呈现的链接。如果不是,它应该返回一个空字符串。现在,ActionLink的是一个静态方法,这使得这一切更加困难。有什么办法来实现什么即时试图做的?

Ok, I want to add some security to my site via the ActionLink method. If the user has enough rights to access the action/controller then the ActionLink should render the link. If not, It should return an empty string. Now, the ActionLink is a static method and that makes it all more difficult. Is there any way to achieve what im trying to do?

推荐答案

新的 AuthorizeActionLink 扩展方法。根据需要过载。

new AuthorizeActionLink extension method. Overload as needed.

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, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes)
{
    if (HasActionPermission(helper, actionName, controllerName))
        return helper.ActionLink(linkText, actionName, controllerName, routeValues, htmlAttributes);

    return MvcHtmlString.Empty;
}

这是做肮脏的工作在搞清楚,如果用户被授权方法

methods that do the dirty work in figuring out if the user is Authorized

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 (IAuthorizationFilter authFilter in actionDescriptor.GetFilters().AuthorizationFilters)
    {
        authFilter.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;
}

这篇关于如何重写ActionLink的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 21:27