IRouteConstraint MVC4上的HttpContextBase.Session和HttpContext.Current.Session都为null

我无法在我的自定义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不为null。 但是当第二次执行时, routeDirection参数设置为System.Web.Routing.RouteDirection.IncomingRequest ,并且会话为null。 为什么?

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

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

总而言之,在IRouteConstraint中无法访问会话,因此不应使用会话。

通常您应该有权访问会话。 但是在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不为null。 什么可能为null是httpContext.Session["IsAuthorized"]如果您从未在会话中为此键设置值,这将是正常的。