C# 路由请求时 HttpContext.Current.Session 为 null
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/218057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HttpContext.Current.Session is null when routing requests
提问by Loki
Without routing, HttpContext.Current.Session
is there so I know that the StateServer
is working. When I route my requests, HttpContext.Current.Session
is null
in the routed page. I am using .NET 3.5 sp1 on IIS 7.0, without the MVC previews. It appears that AcquireRequestState
is never fired when using the routes and so the session variable isn't instantiated/filled.
没有路由,HttpContext.Current.Session
有没有所以我知道它StateServer
正在工作。当我的路线我的要求,HttpContext.Current.Session
是null
在路由页面。我在 IIS 7.0 上使用 .NET 3.5 sp1,没有 MVC 预览。似乎AcquireRequestState
在使用路由时从未被触发,因此会话变量没有被实例化/填充。
When I try to access the Session variables, I get this error:
当我尝试访问 Session 变量时,出现此错误:
base {System.Runtime.InteropServices.ExternalException} = {"Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive. Please also make sure that System.Web.SessionStateModule or a custom session state module is included in the <configuration>.
base {System.Runtime.InteropServices.ExternalException} = {"Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive. Please also make sure that System.Web.SessionStateModule or a custom session state module is included in the <configuration>.
While debugging, I also get the error that the HttpContext.Current.Session
is not accessible in that context.
在调试时,我还收到HttpContext.Current.Session
在该上下文中无法访问的错误。
--
——
My web.config
looks like this:
我的web.config
看起来像这样:
<configuration>
...
<system.web>
<pages enableSessionState="true">
<controls>
...
</controls>
</pages>
...
</system.web>
<sessionState cookieless="AutoDetect" mode="StateServer" timeout="22" />
...
</configuration>
Here's the IRouteHandler implementation:
这是 IRouteHandler 的实现:
public class WebPageRouteHandler : IRouteHandler, IRequiresSessionState
{
public string m_VirtualPath { get; private set; }
public bool m_CheckPhysicalUrlAccess { get; set; }
public WebPageRouteHandler(string virtualPath) : this(virtualPath, false)
{
}
public WebPageRouteHandler(string virtualPath, bool checkPhysicalUrlAccess)
{
m_VirtualPath = virtualPath;
m_CheckPhysicalUrlAccess = checkPhysicalUrlAccess;
}
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
if (m_CheckPhysicalUrlAccess
&& !UrlAuthorizationModule.CheckUrlAccessForPrincipal(
m_VirtualPath,
requestContext.HttpContext.User,
requestContext.HttpContext.Request.HttpMethod))
{
throw new SecurityException();
}
string var = String.Empty;
foreach (var value in requestContext.RouteData.Values)
{
requestContext.HttpContext.Items[value.Key] = value.Value;
}
Page page = BuildManager.CreateInstanceFromVirtualPath(
m_VirtualPath,
typeof(Page)) as Page;// IHttpHandler;
if (page != null)
{
return page;
}
return page;
}
}
I've also tried to put EnableSessionState="True"
on the top of the aspx pages but still, nothing.
我也试过放在EnableSessionState="True"
aspx 页面的顶部,但仍然没有。
Any insights? Should I write another HttpRequestHandler
that implements IRequiresSessionState
?
任何见解?我应该写另一个HttpRequestHandler
实现IRequiresSessionState
吗?
Thanks.
谢谢。
采纳答案by Loki
Got it. Quite stupid, actually. It worked after I removed & added the SessionStateModule like so:
知道了。其实挺傻的 在我删除并添加 SessionStateModule 后它起作用了,如下所示:
<configuration>
...
<system.webServer>
...
<modules>
<remove name="Session" />
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
...
</modules>
</system.webServer>
</configuration>
Simply adding it won't work since "Session" should have already been defined in the machine.config
.
简单地添加它是行不通的,因为“会话”应该已经在machine.config
.
Now, I wonder if that is the usual thing to do. It surely doesn't seem so since it seems so crude...
现在,我想知道这是否是通常的做法。它肯定不是这样,因为它看起来很粗糙......
回答by Bogdan Maxim
回答by Loki
The config section seems sound as it works if when pages are accessed normally. I've tried the other configurations suggested but the problem is still there.
如果正常访问页面时,配置部分看起来很合理。我已经尝试了建议的其他配置,但问题仍然存在。
I doubt the problem is in the Session provider since it works without the routing.
我怀疑问题出在 Session 提供程序中,因为它在没有路由的情况下工作。
回答by tvanfosson
What @Bogdan Maxim said. Or change to use InProc if you're not using an external sesssion state server.
@Bogdan Maxim 所说的。或者,如果您不使用外部会话状态服务器,请更改为使用 InProc。
<sessionState mode="InProc" timeout="20" cookieless="AutoDetect" />
Look herefor more info on the SessionState directive.
看这里有关SessionState的指令的详细信息。
回答by mohammedn
I think this part of code make changes to the context.
我认为这部分代码对上下文进行了更改。
Page page = BuildManager.CreateInstanceFromVirtualPath(
m_VirtualPath,
typeof(Page)) as Page;// IHttpHandler;
Also this part of code is useless:
这部分代码也是无用的:
if (page != null)
{
return page;
}
return page;
It will always return the page wither it's null or not.
无论是否为空,它都会返回页面。
回答by Mike
Nice job! I've been having the exact same problem. Adding and removing the Session module worked perfectly for me too. It didn't however bring back by HttpContext.Current.User so I tried your little trick with the FormsAuth module and sure enough, that did it.
不错的工作!我一直有完全相同的问题。添加和删除 Session 模块对我来说也非常有效。然而它并没有被 HttpContext.Current.User 带回来,所以我用 FormsAuth 模块尝试了你的小技巧,果然,做到了。
<remove name="FormsAuthentication" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule"/>
回答by gandjustas
Just add attribute runAllManagedModulesForAllRequests="true"
to system.webServer\modules
in web.config.
只需在 web.config 中添加属性runAllManagedModulesForAllRequests="true"
即可system.webServer\modules
。
This attribute is enabled by default in MVC and Dynamic Data projects.
此属性在 MVC 和动态数据项目中默认启用。
回答by Alkampfer
a better solution is
更好的解决方案是
runAllManagedModulesForAllRequest is a clever thing to do respect removing and resinserting session module.
runAllManagedModulesForAllRequest 是一件很聪明的事情,可以尊重删除和重新插入会话模块。
alk.
吧。
回答by Frankie Rodriguez
runAllManagedModulesForAllRequests=true
is actually a real bad solution. This increased the load time of my application by 200%. The better solution is to manually remove and add the session object and to avoid the run all managed modules attribute all together.
runAllManagedModulesForAllRequests=true
实际上是一个非常糟糕的解决方案。这使我的应用程序的加载时间增加了 200%。更好的解决方案是手动删除和添加会话对象,并避免将所有托管模块属性一起运行。
回答by Mandeep Janjua
I was missing a reference to System.web.mvc dll in the session adapter, and adding the same fixed the issue.
我在会话适配器中缺少对 System.web.mvc dll 的引用,并添加了相同的引用来解决问题。
Hopefully it will help someone else going through same scenario.
希望它会帮助其他人经历同样的情况。