ASP.Net 4.0 - SiteMap 构建中需要响应吗?

发布于 2024-08-31 07:46:46 字数 2505 浏览 7 评论 0原文

我在将项目升级到 .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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

回梦 2024-09-07 07:46:46

由于在此方面没有任何活动,因此将其作为稍后接受的答案,希望它对其他人有帮助:

我当前的迂回解决方案(实际上是解决方法)是执行 SiteMap< /code> 相关的初始化工作在 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();
  }
}

如果一周内没有人以更好的方法响应,我会接受这一点,但我希望有更好的方法/我错过的东西。

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 in Application_BeginRequest with a check for it to occur once, 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();
  }
}

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文