Я столкнулся с проблемой при обновлении проекта до .Net 4.0 ... и не могу найти причину проблемы (или, по крайней мере, изменения, вызывающие ее). Учитывая свежесть 4.0, пока не так много блогов, поэтому я надеюсь, что у кого-то есть идея. Предисловие: это приложение веб-форм, начиная с версии 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
). Это небольшой 10-килобайтный почтовый индекс, доступный здесь: 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();
}
}
Мне это особенно не нравится, похоже на злоупотребление событием, чтобы обойти проблему. У кого-нибудь есть хотя бы лучший обходной путь, так как поведение .Net 4 с SiteMap вряд ли изменится?