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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:34:59  来源:igfitidea点击:

HttpContext.Current.Session is null when routing requests

c#asp.netroutingsession-variables

提问by Loki

Without routing, HttpContext.Current.Sessionis there so I know that the StateServeris working. When I route my requests, HttpContext.Current.Sessionis nullin the routed page. I am using .NET 3.5 sp1 on IIS 7.0, without the MVC previews. It appears that AcquireRequestStateis never fired when using the routes and so the session variable isn't instantiated/filled.

没有路由,HttpContext.Current.Session有没有所以我知道它StateServer正在工作。当我的路线我的要求,HttpContext.Current.Sessionnull在路由页面。我在 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.Sessionis not accessible in that context.

在调试时,我还收到HttpContext.Current.Session在该上下文中无法访问的错误。

--

——

My web.configlooks 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 HttpRequestHandlerthat 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

It seems that you have forgotten to add your state server address in the configfile.

您似乎忘记在配置文件中添加您的状态服务器地址。

 <sessionstate mode="StateServer" timeout="20" server="127.0.0.1" port="42424" />

回答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\modulesin 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=trueis 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.

希望它会帮助其他人经历同样的情况。