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)


arrow_upward
6
arrow_downward

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

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