我遇到了将项目升级到 .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 站点,所有的花里胡哨都被删除了,只有一个空白的站点地图和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 行为不太可能改变?