ASP.Net 4.0 - SiteMap 构建中需要响应吗?
我在将项目升级到 .Net 4.0 时遇到问题...并且无法找到该问题的任何原因(或者至少是导致该问题的更改)。鉴于 4.0 的新鲜度,目前还没有很多博客来解决问题,所以我希望这里有人有一个想法。前言:这是一个Web Forms应用程序,从3.5 SP1到4.0。
在 Application_Start
事件中,我们迭代 SiteMap 并根据其中的数据构建路由(主要通过添加一些实用程序来美化 URL),但这部分并没有失败......或者至少没有失败还没有走到那一步。
似乎调用 SiteMap.RootNode (在 application_start 内部)导致 4.0 吃掉它,因为 XmlSiteMapProvider.GetNodeFromXmlNode
方法已更改,在反射器中查看,您可以看到它正在命中 HttpResponse.ApplyAppPathModifier
此处:
str2 = HttpContext.Current.Response.ApplyAppPathModifier(str2);
HttpResponse
在 2.0 CLR 中,这个方法根本没有使用过,所以我们工作得很好,但在 4.0 中,该方法是作为这个堆栈的结果被调用的:
[HttpException (0x80004005): Response is not available in this context.]
System.Web.XmlSiteMapProvider.GetNodeFromXmlNode(XmlNode xmlNode, Queue queue)
System.Web.XmlSiteMapProvider.ConvertFromXmlNode(Queue queue)
System.Web.XmlSiteMapProvider.BuildSiteMap()
System.Web.XmlSiteMapProvider.get_RootNode()
System.Web.SiteMap.get_RootNode()
因为 Response
在这里不可用在 4.0 中,我们收到错误。要重现这一点,您可以将测试用例缩小到全局范围:
protected void Application_Start(object sender, EventArgs e)
{
var s = SiteMap.RootNode; //Kaboom!
//or just var r = Context.Response;
//or var r = HttpContext.Current.Response;
//all result in the same "not available" error
}
问题:我在这里遗漏了一些明显的东西吗? 或者,是否在 4.0 中添加了另一个推荐用于与以下内容相关的事件:启动时的 SiteMap?
对于任何好奇/愿意提供帮助的人,我创建了一个非常小的项目(默认的 VS 2010 ASP.Net 4.0 站点,所有花哨的功能都被删除,只有一个空白的站点地图和 <添加了 code>Application_Start 代码)。这是一个 10kb 的小 zip 文件,可在此处获取: http://www.ncraver.com/Test/SiteMapTest.zip
更新:
不是一个很好的解决方案,但当前的解决方法是在 Application_BeginRequest
中完成工作,如下所示:
private static bool routesRegistered = false;
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (!routesRegistered)
{
Application.Lock();
if (!routesRegistered) RouteManager.RegisterRoutes(RouteTable.Routes);
routesRegistered = true;
Application.UnLock();
}
}
我特别不喜欢这个,感觉像是滥用该事件来绕过该问题。由于 SiteMap 的 .Net 4 行为不太可能改变,是否有人至少有更好的解决方法?
I'm running into an issue upgrading a project to .Net 4.0...and having trouble finding any reason for the issue (or at least, the change causing it). Given the freshness of 4.0, not a lot of blogs out there for issues yet, so I'm hoping someone here has an idea. Preface: this is a Web Forms application, coming from 3.5 SP1 to 4.0.
In the Application_Start
event we're iterating through the SiteMap and constructing routes based off data there (prettifying URLs mostly with some utility added), that part isn't failing though...or at least isn't not getting that far.
It seems that calling the SiteMap.RootNode (inside application_start) causes 4.0 to eat it, since the XmlSiteMapProvider.GetNodeFromXmlNode
method has been changed, looking in reflector you can see it's hitting HttpResponse.ApplyAppPathModifier
here:
str2 = HttpContext.Current.Response.ApplyAppPathModifier(str2);
HttpResponse
wasn't used at all in this method in the 2.0 CLR, so what we had worked fine, in 4.0 though, that method is called as a result of this stack:
[HttpException (0x80004005): Response is not available in this context.]
System.Web.XmlSiteMapProvider.GetNodeFromXmlNode(XmlNode xmlNode, Queue queue)
System.Web.XmlSiteMapProvider.ConvertFromXmlNode(Queue queue)
System.Web.XmlSiteMapProvider.BuildSiteMap()
System.Web.XmlSiteMapProvider.get_RootNode()
System.Web.SiteMap.get_RootNode()
Since Response
isn't available here in 4.0, we get an error. To reproduce this, you can narrow the test case down to this in global:
protected void Application_Start(object sender, EventArgs e)
{
var s = SiteMap.RootNode; //Kaboom!
//or just var r = Context.Response;
//or var r = HttpContext.Current.Response;
//all result in the same "not available" error
}
Question: Am I missing something obvious here? Or, is there another event added in 4.0 that's recommended for anything related to SiteMap on startup?
For anyone curious/willing to help, I've created a very minimal project (a default VS 2010 ASP.Net 4.0 site, all the bells & whistles removed and only a blank sitemap and the Application_Start
code added). It's a small 10kb zip available here: http://www.ncraver.com/Test/SiteMapTest.zip
Update:
Not a great solution, but the current work-around is to do the work in Application_BeginRequest
, like this:
private static bool routesRegistered = false;
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (!routesRegistered)
{
Application.Lock();
if (!routesRegistered) RouteManager.RegisterRoutes(RouteTable.Routes);
routesRegistered = true;
Application.UnLock();
}
}
I don't like this particularly, feels like an abuse of the event to bypass the issue. Does anyone have at least a better work-around, since the .Net 4 behavior with SiteMap is not likely to change?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于在此方面没有任何活动,因此将其作为稍后接受的答案,希望它对其他人有帮助:
我当前的迂回解决方案(实际上是解决方法)是执行
SiteMap< /code> 相关的初始化工作在
Application_BeginRequest
中进行,并检查它是否发生一次,如下所示:如果一周内没有人以更好的方法响应,我会接受这一点,但我希望有更好的方法/我错过的东西。
Since there has been no activity on this, leaving this as the answer to accept later, hoping it helps someone else:
My current round-about solution (workaround really) is to do the
SiteMap
related initialization work inApplication_BeginRequest
with a check for it to occur once, like this:If no one responds with a better method in a week I'll accept this, but I'm hoping there's a better way/something I've missed.