HttpContext.Current.Session 为空 + OWIN
HttpContext.Current.Session is null + OWIN
我是 OWIN 的新手,这个问题一直是我的主要障碍。
基本上,在我的 MVC 应用程序中,我在启动时有以下内容 class:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = OfficeSettings.ClientId,
Authority = OfficeSettings.Authority,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters()
{
RoleClaimType = "roles"
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthorizationCodeReceived = (context) =>
{
// code hidden for readability
if(HttpContext.Current.Session == null)
{
// It's null. Why is that?
}
var session = HttpContext.Current.Session;
if (session["myMockSession"] != null)
{
// Do stuff...
}
},
RedirectToIdentityProvider = (context) =>
{
// code hidden for readability
},
AuthenticationFailed = (context) =>
{
// code hidden for readability
}
}
});
我不明白为什么调试的时候Session是空的。 HttpContext.Current 属性 不是。 Sessions + OWIN 有什么限制吗?这个问题有什么解决方法吗?应该如何处理它?
旁注 1:
我试图添加我在其中一个 SO 问题中找到的这段代码,但会话仍然为空:
app.Use((context, next) =>
{
// Depending on the handler the request gets mapped to, session might not be enabled. Force it on.
HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
return next();
});
旁注 2:
我似乎再也找不到它了,但是有人在 SO 问题之一中建议在 Global.asax 处添加空方法 Session_Start 和 Session_End(作为空方法)。那也没用。
我欢迎任何建议。
谢谢!
你快了。
您的会话仍然为空的原因是您没有指示 OWIN 在执行中间件之前初始化 System.Web 会话。
通过添加 .UseStageMarker(..) 在 您的中间件注册之后,您将告诉 OWIN 它应该在执行管道中的哪个位置执行SetSessionStateBehaviour
app.Use((context, next) =>
{
var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
return next();
});
// To make sure the above `Use` is in the correct position:
app.UseStageMarker(PipelineStage.MapHandler);
默认情况下,Owin 中间件 运行 在最后一个事件 (PipelineStage.PreHandlerExecute) 中对你来说太晚了。
现在,要使用会话,您需要在 second 中间件中工作,即 运行s after session已在 Asp.Net 运行 时间获得。这个中间件必须是运行在PostAquireState阶段,像这样:
.Use((context, next) =>
{
// now use the session
HttpContext.Current.Session["test"] = 1;
return next();
})
.UseStageMarker(PipelineStage.PostAcquireState);
Asp.Net katana 文档有一个关于中间件如何工作的 excellent article。
有关 Asp.net 中执行顺序的详细信息,请参阅 PiplineStage enum docs and the HttpApplication 文档。
我是 OWIN 的新手,这个问题一直是我的主要障碍。
基本上,在我的 MVC 应用程序中,我在启动时有以下内容 class:
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationOptions());
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = OfficeSettings.ClientId,
Authority = OfficeSettings.Authority,
TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters()
{
RoleClaimType = "roles"
},
Notifications = new OpenIdConnectAuthenticationNotifications()
{
AuthorizationCodeReceived = (context) =>
{
// code hidden for readability
if(HttpContext.Current.Session == null)
{
// It's null. Why is that?
}
var session = HttpContext.Current.Session;
if (session["myMockSession"] != null)
{
// Do stuff...
}
},
RedirectToIdentityProvider = (context) =>
{
// code hidden for readability
},
AuthenticationFailed = (context) =>
{
// code hidden for readability
}
}
});
我不明白为什么调试的时候Session是空的。 HttpContext.Current 属性 不是。 Sessions + OWIN 有什么限制吗?这个问题有什么解决方法吗?应该如何处理它?
旁注 1: 我试图添加我在其中一个 SO 问题中找到的这段代码,但会话仍然为空:
app.Use((context, next) =>
{
// Depending on the handler the request gets mapped to, session might not be enabled. Force it on.
HttpContextBase httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
return next();
});
旁注 2: 我似乎再也找不到它了,但是有人在 SO 问题之一中建议在 Global.asax 处添加空方法 Session_Start 和 Session_End(作为空方法)。那也没用。
我欢迎任何建议。 谢谢!
你快了。 您的会话仍然为空的原因是您没有指示 OWIN 在执行中间件之前初始化 System.Web 会话。
通过添加 .UseStageMarker(..) 在 您的中间件注册之后,您将告诉 OWIN 它应该在执行管道中的哪个位置执行SetSessionStateBehaviour
app.Use((context, next) =>
{
var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName);
httpContext.SetSessionStateBehavior(SessionStateBehavior.Required);
return next();
});
// To make sure the above `Use` is in the correct position:
app.UseStageMarker(PipelineStage.MapHandler);
默认情况下,Owin 中间件 运行 在最后一个事件 (PipelineStage.PreHandlerExecute) 中对你来说太晚了。
现在,要使用会话,您需要在 second 中间件中工作,即 运行s after session已在 Asp.Net 运行 时间获得。这个中间件必须是运行在PostAquireState阶段,像这样:
.Use((context, next) =>
{
// now use the session
HttpContext.Current.Session["test"] = 1;
return next();
})
.UseStageMarker(PipelineStage.PostAcquireState);
Asp.Net katana 文档有一个关于中间件如何工作的 excellent article。 有关 Asp.net 中执行顺序的详细信息,请参阅 PiplineStage enum docs and the HttpApplication 文档。