asp.net-mvc-2 - 如何覆盖 ActionLink 行为

标签 asp.net-mvc-2 overriding actionlink

好的,我想通过 ActionLink 方法为我的网站添加一些安全性。如果用户有足够的权限来访问操作/ Controller ,则 ActionLink 应呈现该链接。如果不是,它应该返回一个空字符串。现在,ActionLink 是一个静态方法,这使得一切变得更加困难。有什么办法可以实现我想要做的事情吗?

最佳答案

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

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

在确定用户是否获得授权方面做肮脏工作的方法

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

关于asp.net-mvc-2 - 如何覆盖 ActionLink 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5477019/

相关文章:

asp.net-mvc - 如何使用 MVC(4)创建(图像)标题 Logo

ajax - 如何处理 .ajax 帖子中的 FileStream 返回类型?

c# - 为什么我的路由测试失败,但运行应用程序时路由有效?

html - ASP 网络 MVC2 : <div> tag - "float: left;" - Problem?

swift - 未调用快速扩展中的通用覆盖

c++ - 覆盖非虚拟方法

html - MVC2 : Is there an Html Helper for raw Html?

asp.net-mvc - IE8 中 jquery UI 弹出窗口内的 ajax 表单问题

c# - 使用更指定的返回类型(协方差)覆盖抽象属性

c# - 如何在 ActionLink 的字符串部分添加换行符?