c# – 在浏览器中加载虚拟目录名时,AcquireRequestState中的会话为空,加载Default.aspx时,会话为空

c# – 在浏览器中加载虚拟目录名时,AcquireRequestState中的会话为空,加载Default.aspx时,会话为空,第1张

概述我有一个ASP.NET 4.0 WebForms应用程序.我需要访问HttpContext.Current.Session并在Global.asax中的AcquireRequestState事件(或其后的事件)中设置一个值,我发现了一个特殊的行为. 假设我在IIS(虚拟版本7)中有一个名为Foo的虚拟目录.因为我的Default.aspx作为主页. Global.asax示例文件如下: <%@ A 我有一个ASP.NET 4.0 WebForms应用程序.我需要访问httpContext.Current.Session并在Global.asax中的AcquireRequestState事件(或其后的事件)中设置一个值,我发现了一个特殊的行为.

假设我在IIS(虚拟版本7)中有一个名为Foo的虚拟目录.因为我的Default.aspx作为主页. Global.asax示例文件如下:

<%@ Application Language="C#" %><script runat="server">    voID Application_AcquireRequestState(object sender,EventArgs e)    {        httpContext.Current.Session["key"] = "value";    }</script>

当我在浏览器中访问http://localhost/Foo/Default.aspx时,工作正常.当我访问http:// localhost / Foo /我得到一个NullReferenceException,我在会话中设置值.唯一的变化是浏览器中的URL.它们最终会击中同一页面,但是框架的行为方式与URL是否仅包含文件夹名称有关,还是包含aspx文件.

检查是否(httpContext.Current.Session!= null)对我来说不是一个选项,因为我需要在会话中为每个请求设置一个值,这是不可协商的.

在IIS中有一个配置设置,我错过了,还是这个BUG /被遗忘的功能?

another question的答案暗示了IIS不会为每种请求加载会话,例如样式表不需要会话.也许这种行为是发生的,因为IIS无法提前告知该文件夹名称是否会导致执行一个aspx文件,或者是否会传递静态HTML文件?

更新:我甚至尝试重新排序IIS查找的默认文档,以便“default.aspx”在列表的顶部,例如

> default.aspx
> Default.asp
> Default.htm
> …

而且我仍然遇到同样的问题.

更新:

事件处理程序只会被触发一次,因为它导致了一个NullReferenceException.我已经做了一些额外的阅读,我知道ASP.NET为每个请求触发这些事件,即使是CSS或JavaScript文件.另外,会话对象没有为静态文件加载,因为没有访问会话的代码,因此不需要加载该对象.即使如此,第一个请求是对网页的请求,这将需要会话,会话为空.

@DmytroShevchenko问:

First add a guard check if (httpContext.Current.Session != null) so that there is no NullReferenceException thrown. Then try to see,maybe the event will be fired a second time,with a session available.

修改代码:

voID Application_AcquireRequestState(object sender,EventArgs e){    if (httpContext.Current.Session != null)    {        httpContext.Current.Session["key"] = "value";    }}

我在if语句中设置了一个断点.我看到这个事件发生4次:

> session为null
> session为null
> session not null
> session为null

当继续每次执行代码时,只有当它开始执行Default.aspx及其代码隐藏时,我有一个会话可用.我实际上在firefox中打开了网页,并正在监控网络请求.第一个请求是针对http:// localhost / Foo /.

接下来我在Application_BeginRequest中设置一个断点,并得到以下事件:

> BeginRequest
> AcquireRequestState
> BeginRequest
> AcquireRequestState
> BeginRequest
> AcquireRequestState(会话不为空)
>执行Default.aspx(/ Foo返回对浏览器的响应)
> BeginRequest
> AcquireRequestState(会话再次为null)

在#9,浏览器中的AJAX请求到http:// localhost:54859 / 8fad4e71e57a4caebe1c6ed7af6f583a / arterySignalR / poll?transport = longPolling& connectionToken = …& messageID = …& requestUrl = http:// localhost / Foo /& browsername = firefox& userAgent = Mozilla / 5.0(windows NT 6.1; WOW64; rv:41.0)Gecko / 20100101 firefox / 41.0& tID = 4& _ = 1445346977956正在等待响应.

解决方法 我发现 a discussion关于通过其显式URL提供页面和提供默认文档之间的差异.

使用MVC和WebAPI,引入了一个新的httpModule:ExtensionlessUrlHandler.我相信您的事件多次发射(只有一次会话可用)可能是由该模块或ASP.NET的其他(重新)路由逻辑引起的,该逻辑实际上重定向ASP.NET来处理Default.aspx.

另外,正如你自己提到的,这些事件可以被触发为静态文件请求.

最重要的是,每当你的事件触发时,你不应该依靠会话.但是,假设您可以在提供ASP.NET页面时至少访问一次会话是安全的.因此,这是你的代码应该如下所示:

voID Application_AcquireRequestState(object sender,EventArgs e){    if (httpContext.Current.Session != null)    {        httpContext.Current.Session["key"] = "value";    }}
总结

以上是内存溢出为你收集整理的c# – 在浏览器中加载虚拟目录名时,AcquireRequestState中的会话为空,加载Default.aspx时,会话为空全部内容,希望文章能够帮你解决c# – 在浏览器中加载虚拟目录名时,AcquireRequestState中的会话为空,加载Default.aspx时,会话为空所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1259405.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存