2011-12-27 13 views
15

Z jakiegoś powodu, gdy niektóre boty odwiedzają witrynę, generowanie adresu URL za pomocą metody UrlHelper.Action powoduje zgłoszenie wyjątku zerowego z System.Web.HttpServerVarsCollection.Get. Zrobiłem kilka debugowania i zestaw wywołań rozpoczyna się od próby uzyskania "HTTP_X_ORIGINAL_URL" z kolekcji HttpContextBase.Request.ServerVariables.Null wyjątku odniesienia podczas generowania adresu URL z UrlHelper.Action method

Jeśli odwiedzę ten sam adres bezpośrednio z przeglądarki - nie ma problemu. Strona jest serwerem i nie jest rejestrowany żaden błąd. Wydaje się, że pojawia się tylko wtedy, gdy odwiedza go bot.

Nie wiem, czy jest to istotne, czy nie, ale witryna została właśnie przeniesiona do wersji IIS 7.5. Nadal używa .NET 2.0 w trybie zintegrowanym.

Patrząc na kod jako odwrócony przez Reflector, jedynym miejscem, w którym wyjątek zerowy może wystąpić bezpośrednio w metodzie Get jest połączenie z this._request.FetchServerVariables. Tak jakby kompletne żądanie nie zostało poprawnie skonfigurowane.

Czy ktoś inny spotkał się z tym problemem lub znalazł rozwiązanie? Dlaczego wniosek miałby być inaczej konfigurowany, gdy odwiedził go bot?

UPDATE: Niektóre dodatkowe debugowanie wykazały, że HttpServerVarsCollection została zbyta, wraz z jego rodzicem HttpRequest przedmiot. Pytanie brzmi teraz: w jaki sposób obiekt żądania zwrócony przez HttpContext.Current może zostać ujawniony przed zakończeniem żądania?

HttpServerVarsCollection.Get Metoda

public override string Get(string name) 
{ 
    if (!this._populated) 
    { 
     string simpleServerVar = this.GetSimpleServerVar(name); 
     if (simpleServerVar != null) 
     { 
      return simpleServerVar; 
     } 
     this.Populate(); 
    } 
    if (this._iis7workerRequest == null) 
    { 
     return this.GetServerVar(base.BaseGet(name)); 
    } 
    string serverVar = this.GetServerVar(base.BaseGet(name)); 
    if (string.IsNullOrEmpty(serverVar)) 
    { 
     // Only place null reference can happen 
     serverVar = this._request.FetchServerVariable(name); 
    } 
    return serverVar; 
} 

Pełny stos ślad

NullReferenceException: Object reference not set to an instance of an object.] 
    System.Web.HttpServerVarsCollection.Get(String name) +8645730 
    System.Collections.Specialized.NameValueCollection.get_Item(String name) +7 
    System.Web.Mvc.PathHelpers.GenerateClientUrlInternal(HttpContextBase httpContext, String contentPath) in C:\Dev\Site\MVC\Microsoft\src\SystemWebMvc\Mvc\PathHelpers.cs:39 
    System.Web.Mvc.PathHelpers.GenerateClientUrl(HttpContextBase httpContext, String contentPath) in C:\Dev\Site\MVC\Microsoft\src\SystemWebMvc\Mvc\PathHelpers.cs:21 
    System.Web.Mvc.UrlHelper.GenerateUrl(String routeName, String actionName, String controllerName, RouteValueDictionary routeValues, RouteCollection routeCollection, RequestContext requestContext, Boolean includeImplicitMvcValues) in C:\Dev\Site\MVC\Microsoft\src\SystemWebMvc\Mvc\UrlHelper.cs:136 
    System.Web.Mvc.UrlHelper.GenerateUrl(String routeName, String actionName, String controllerName, RouteValueDictionary routeValues) in C:\Dev\Site\MVC\Microsoft\src\SystemWebMvc\Mvc\UrlHelper.cs:101 
    System.Web.Mvc.UrlHelper.Action(String actionName, String controllerName, Object routeValues) in C:\Dev\Site\MVC\Microsoft\src\SystemWebMvc\Mvc\UrlHelper.cs:51 
    www.CmsExtensions.Document(UrlHelper urlHelper, String path) in C:\Dev\Site\www\Code\CmsExtensions.cs:33 
    www.CmsExtensions.Document(UrlHelper urlHelper, Document document) in C:\Dev\Site\www\Code\CmsExtensions.cs:20 
    www.<>c__DisplayClass17.<Load>b__c(Document d) in C:\Dev\Site\www\Global.asax.cs:251 
    Fringine.Cms.DocumentContentParser.ReplaceDocumentRefs(IResolvingDocumentCache cache, Match match) +258 
    Fringine.Cms.<>c__DisplayClass4.<ParseContent>b__2(Match m) +17 
    System.Text.RegularExpressions.RegexReplacement.Replace(MatchEvaluator evaluator, Regex regex, String input, Int32 count, Int32 startat) +234 
    System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator, Int32 count, Int32 startat) +28 
    System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator) +38 
    System.Text.RegularExpressions.Regex.Replace(String input, String pattern, MatchEvaluator evaluator, RegexOptions options) +47 
    Fringine.Cms.DocumentContentParser.ParseContent(String content, IResolvingDocumentCache cache) +83 
    Fringine.Cms.ResolvingDocumentCache.<Parse>b__0(String d) +21 
    Fringine.Cms.DocumentCache.GetParsedData(String id, String content, IDocumentService documentService, Func`2 parser) +216 
    Fringine.Cms.ResolvingDocumentCache.Parse(String id, String content) +67 
    Fringine.Cms.CachedDocument.GetSummary() +966 
    Fringine.Cms.CachedDocument.get_Summary() +19 
    ASP.views_document_widget_feeddocumentsummary_ascx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) +841 
    System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +256 
    System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +19 
    System.Web.UI.Control.Render(HtmlTextWriter writer) +10 
    System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +99 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 
    System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +134 
    System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +19 
    System.Web.UI.Page.Render(HtmlTextWriter writer) +29 
    System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer) in C:\Dev\Site\MVC\Microsoft\src\SystemWebMvc\Mvc\ViewPage.cs:107 
    System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +99 
    System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25 
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1266 
+0

'HttpContext.Current.Request' nie powinien zostać usunięty przed ukończeniem żądania. Czy masz może kod, który mówi 'using (HttpContext.Current.Request)' lub odpowiednik? –

+1

Nie ... to była jedna z niewielu rzeczy, o których początkowo myślałem. Sprawdziłem cały kod jaki posiadam i nic nie czyni jawnego (lub niejawnego przy użyciu) wywołania Dispose na obiekcie żądania. Zdecydowałem się jednak poprzez więcej debugowania, że ​​występuje tylko w trybie zintegrowanym IIS 7 - nie w klasycznym lub na serwerze programistycznym ASP.NET. –

+0

Faktycznie potwierdziłem tylko w IIS 7.5 o Windows 7 i 2008 R2. W rzeczywistości nie testowałem IIs 7.0. –

Odpowiedz

1

Wiem, że to pytanie jest dość stary teraz, ale niedawno znalazłam się w bardzo podobnej sytuacji, gdzie mój UrlHelper podawał mi również zerowy wyjątek referencyjny w System.Web.HttpServerVarsCollection.Get.

Problem był rzeczywiście HTTP_X_ORIGINAL_URL i ta konkretna zmienna serwerowa pochodzi z URL Rewrite 2.0 Module na IIS.

Co ciekawe moduł ten został zainstalowany, ale nie był używany. Jednak sama obecność wystarczyła, aby spowodować problem. Odinstalowanie go spowodowało, że błąd zniknął.

Jeśli chcesz zrobić ponowne zapisywanie adresów URL, istnieją inne moduły lub możesz to zrobić na poziomie aplikacji.

Nadzieję, że pomaga.

3

Miałem ten problem, ale nie miało to związku z modułami do przepisywania adresów URL.

W moim przypadku przypadkowo buforowałem instancję UrlHelper w polu statycznym, a późniejsze żądania napotkały unieszkodliwioną instancję z wcześniejszych żądań.

+0

to prawdopodobnie zaoszczędziło mi tydzień debugowania, dziękuję – AaronHS

1

Wpadłem na to, w moim przypadku udało się rozwiązać, przełączając się na użycie metody UrlHelper bez użycia rozszerzenia. Miałem jedną metodę rozszerzenia wywołującą inną, ale przekazującą UrlHelper do drugiej metody.

ten sposób została złamana:

public static string Script(this UrlHelper helper, string fileName) 
{ 
    return Asset(helper, "~/js/", fileName); 
} 

private static string Asset(this UrlHelper helper, string path, string fileName) 
{ 
    return helper.Content(string.Format("{0}/{1}/{2}", 
      path, 
      Version, 
      fileName)); 
} 

ten sposób działa:

public static string Script(this UrlHelper helper, string fileName) 
{ 
    return Asset(helper, "~/js/", fileName); 
} 

private static string Asset(UrlHelper helper, string path, string fileName) 
{ 
    return helper.Content(string.Format("{0}/{1}/{2}", 
      path, 
      Version, 
      fileName)); 
} 

zauważyć różnicę podpis funkcja metody aktywów.

Powiązane problemy