【问题标题】:UrlHelper and ViewContext inside an Authorization Attribute授权属性中的 UrlHelper 和 ViewContext
【发布时间】:2026-01-28 08:55:01
【问题描述】:

我有一个我无法解决的场景:

我正在为 mvc 创建我自己的自定义授权属性。我想添加的主要功能是能够在用户不在特定角色时更改用户被重定向的位置。如果他们没有经过身份验证,我不介意系统将它们发送回登录页面,但是如果他们经过身份验证但不允许访问该操作方法,我想选择将它们发送到哪里。

这是我想做的:

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
        public string Action;
        public string Controller;

        protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
        {
            // if User is authenticated but not in the correct role
            string url = Url.Action(this.Action, this.Controller);                
            httpContext.Response.Redirect(url);
        }
    }

作为额外的奖励,我希望在进行重定向之前访问 ViewContext 和 TempData。

关于如何在属性中实例化 UrlHelper 和 ViewContext 有什么想法吗?

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-membership httpcontext custom-attributes


    【解决方案1】:

    您可以覆盖OnAuthorization 方法:

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }
    
        // Call the AuthorizeCore which should return true or false
        if (!this.AuthorizeCore(filterContext.HttpContext))
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary()
            {
                { "controller", "home" },
                { "action", "about" },
                { "id", "foo" },
            });
        }
    }
    

    就 ViewData 和 TempData 而言:filterContext.Controller.ViewDatafilterContext.Controller.TempData 应该在 OnAuthorization 方法中工作。最后,如果您希望使用UrlHelper(在这种情况下没有必要,因为RedirectToRouteResult 更好)您可以实例化它:

    var urlHelper = new UrlHelper(filterContext.RequestContext);
    

    【讨论】:

    • 太棒了,谢谢。在查看您的回复后,我意识到我可以简单地问“我该如何获取 AuthorizationContext。”一旦我有了它,我就很危险。
    • 注意:实现 OnAuthorization() 方法并非易事。如果您选择覆盖 OnAuthorization() 而不是 AuthorizeCore(),请在 OnAuthorization() 中添加代码以禁用或挂钩输出缓存。请参阅forums.asp.net/p/1533590/3737756.aspx 了解更多信息。