【发布时间】:2015-02-16 14:31:51
【问题描述】:
原则上我想做的事情很简单,但是 ASP.NET 页面的生命周期给我泼了一盆冷水。
问题来了
我们已经实现了 URL 重定向,并且我在 Global.ASAX 的 Sub Application_BeginRequest 上继承了类似这样的代码:
dv.Table = CommonFunctions.ConvertXmlFileToDataSet("/XmlData/WebAppFolders.xml").Tables("Application")
dv.RowFilter = "'" + fullOrigionalPath + "' LIKE '%'+ folder + '%'"
If dv.Count > 0 Then 'match on key to redirect
If fullOrigionalPath.EndsWith(dv(0)("folder") + "/") Then
Context.RewritePath(dv(0)("basePage"), True)
Else 'missing page in directory --> redirect
HttpContext.Current.Items("Raise404") = "true"
Response.Redirect("/" + dv(0)("folder"))
End If
Return
End If
基本上,我们正在读取一个包含 URL 重定向的大型 XML 文件。这工作正常。问题发生在行...
HttpContext.Current.Items("Raise404") = "true"
在 Application_BeginRequest 的上下文中,会话对象尚不可用,因此我无法使用它来存储我命名为 Raise404 的标志。相反,我不得不求助于使用 Items 集合。
发生重定向时会出现问题。新的页面生命周期会破坏 Items 数组并用新的空数组覆盖它。
当我尝试使用我的标志 Raise404 时,它已不再存在于我的页面 PreRender 事件中。
为了使事情复杂化,我们使用母版页,所以我被要求将我们想要执行的代码放在母版页中
理想情况下,如果 Items 数组没有被破坏,那么这段代码就可以工作:
Private Sub Page_PreRender(sender As Object, e As System.EventArgs) Handles Me.PreRender
If HttpContext.Current.Items("Raise404") IsNot Nothing AndAlso HttpContext.Current.Items("Raise404").Equals("true") Then
Response.StatusCode = 404
HttpContext.Current.Items("Raise404") = Nothing
End If
End Sub
我不确定我可以使用哪种变量来存储我的标志并让它在重定向中存活下来。
有什么想法吗?
更新:问题在于为我的请求提供服务的 HTTP 处理程序是 System.Web.DefaultHTTPHandler,它没有实现 IRequiresSessionState,因此当我的请求在 Global ASAX 内部处理时,没有创建会话。因此,解决方案似乎是编写一个实现 IRequiresSessionState 的自定义 HTTPHandler,并将其用于我的所有 .aspx 文件。即便如此,在引发 PreRequestHandlerExecute 之前,不会在 Global.ASAX 中创建会话状态。所以,把它们放在一起,我认为我需要编写一个实现 IRequiresSessionState 的自定义 HTTP 处理程序,并延迟页面的重定向,直到 PreRequestHandlerExecute 被引发,在那里我可以将我的标志存储到会话状态中,并且只有在那之后,重定向我的页面。
不是很优雅,我想知道是否会影响性能。
【问题讨论】:
标签: asp.net vb.net page-lifecycle