ASP.Net 4.0 - Требуется ответ при построении SiteMap?

Я столкнулся с проблемой при обновлении проекта до .Net 4.0 ... и не могу найти причину проблемы (или, по крайней мере, вызвавшее ее изменение). Учитывая свежесть 4.0, пока не так много блогов с описанием проблем, поэтому я надеюсь, что у кого-то есть идея. Предисловие: это приложение веб-форм, начиная с версии 3.5 SP1 до 4.0.

В событии Application_Start мы перебираем SiteMap и строим маршруты на основе имеющихся там данных (в основном уточняем URL-адреса с помощью некоторой добавленной утилиты), но эта часть не дает сбоев ... или, по крайней мере, не заходит так далеко.

Похоже, что вызов SiteMap.RootNode (внутри application_start) заставляет 4.0 его съесть, поскольку метод XmlSiteMapProvider.GetNodeFromXmlNode был изменен, глядя в отражатель, вы можете увидеть, что он попадает в _ 3_ здесь:

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). Это небольшой zip-архив размером 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 вряд ли изменится?


person Nick Craver    schedule 03.05.2010    source источник


Ответы (1)


Поскольку по этому поводу не было никаких действий, оставьте это как ответ, чтобы принять его позже, надеясь, что это поможет кому-то другому:

Мое текущее обходное решение (на самом деле обходной путь) состоит в том, чтобы выполнить SiteMap связанную инициализацию в 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();
  }
}

Если через неделю никто не предложит лучший метод, я приму его, но я надеюсь, что есть лучший способ / что-то, что я пропустил.

person Nick Craver    schedule 24.05.2010