2

我无法在我的自定义 RootConstraint 类上访问 Session,它设置为 null。我已经搜索但找不到解决方案。

public class AdminRootConstraint : IRouteConstraint
{
    public bool Match
        (
            HttpContextBase httpContext,
            Route route,
            string parameterName,
            RouteValueDictionary values,
            RouteDirection routeDirection
        )
    {
        if ((string) values["controller"] == "Login")
            return true;

        return HttpContext.Current.Session != null && (bool)HttpContext.Current.Session["IsAuthorized"];
    }
}

编辑

这是 httpContext 参数在即时窗口上的样子。梅给出了一个主意。

httpContext
{System.Web.HttpContextWrapper}
    [System.Web.HttpContextWrapper]: {System.Web.HttpContextWrapper}
    AllErrors: null
    AllowAsyncDuringSyncStages: false
    Application: {System.Web.HttpApplicationStateWrapper}
    ApplicationInstance: {ASP.global_asax}
    AsyncPreloadMode: None
    Cache: {System.Web.Caching.Cache}
    CurrentHandler: null
    CurrentNotification: ResolveRequestCache
    Error: null
    Handler: null
    IsCustomErrorEnabled: false
    IsDebuggingEnabled: true
    IsPostNotification: true
    IsWebSocketRequest: false
    IsWebSocketRequestUpgrading: false
    Items: Count = 0x00000000
    PageInstrumentation: {System.Web.Instrumentation.PageInstrumentationService}
    PreviousHandler: null
    Profile: null
    Request: {System.Web.HttpRequestWrapper}
    Response: {System.Web.HttpResponseWrapper}
    Server: {System.Web.HttpServerUtilityWrapper}
    Session: null
    SkipAuthorization: false
    ThreadAbortOnTimeout: true
    Timestamp: {14.09.2013 16:52:53}
    Trace: {System.Web.TraceContext}
    User: {System.Security.Principal.WindowsPrincipal}
    WebSocketNegotiatedProtocol: null
    WebSocketRequestedProtocols: null

编辑 2

我正在使用RedirectToAction同一区域中的操作中的方法,并且该Match方法在我跟踪时执行了两次。第一次执行时,routeDirection参数设置为System.Web.Routing.RouteDirection.UrlGeneration,此时 Session 不为空。但是当第二次执行时,routeDirection参数设置为System.Web.Routing.RouteDirection.IncomingRequest并且会话为空。为什么?

4

2 回答 2

2

第一次调用 Match 是因为 MVC 正在构建 URL,它将导航用户的浏览器(通过发送 HTTP 302)。这一次你偶然有会话只是因为它存在于那个时刻。

第二次调用 Match 是在请求​​到达浏览器时。这次会话不存在,因为路由逻辑是在加载会话之前执行的。例如,路由可能会呈现根本不需要会话的页面。

总而言之,会话在 IRouteConstraint 中不可访问,不应使用。

于 2015-04-17T14:29:36.037 回答
0

通常,您应该有权访问会话。但是在 ASP.NET MVC 应用程序中避免使用HttpContext.Current静态属性。请改用HttpContextBase提供给您的抽象:

public class AdminRootConstraint : IRouteConstraint
{
    public bool Match
    (
        HttpContextBase httpContext,
        Route route,
        string parameterName,
        RouteValueDictionary values,
        RouteDirection routeDirection
    )
    {
        if ((string) values["controller"] == "Login")
        {
            return true;
        }

        object isAuthorized = httpContext.Session["IsAuthorized"];
        return (isAuthorized != null && (bool)isAuthorized);
    }
}

在此示例httpContext.Session中不会为空。httpContext.Session["IsAuthorized"]如果您从未在会话中为该键设置值,则可能为 null 的情况是正常的。

于 2013-09-14T12:55:14.930 回答