2011-12-27 13 views
15

Per alcuni motivi, quando alcuni robot visitano il sito, la generazione di un url con il metodo UrlHelper.Action genera un'eccezione null da System.Web.HttpServerVarsCollection.Get. Ho eseguito alcune operazioni di debug e lo stack delle chiamate ha avuto origine con il tentativo di ottenere "HTTP_X_ORIGINAL_URL" dalla raccolta HttpContextBase.Request.ServerVariables.Eccezione di riferimento null durante la generazione di un url con UrlHelper.Action metodo

Se visito lo stesso indirizzo direttamente da un browser, nessun problema. La pagina è server e non viene registrato alcun errore. Sembra solo che si verifichi quando viene visitato da un bot.

Non sicuro se pertinente o meno, ma il sito è stato appena migrato su IIS 7.5. Ancora utilizzando .NET 2.0 in modalità integrata.

Osservando il codice come invertito da Reflector, l'unica posizione in cui può verificarsi un'eccezione null direttamente nel metodo Get è la chiamata a this._request.FetchServerVariables. Come se la richiesta completa non fosse stata impostata correttamente.

Qualcun altro ha affrontato questo problema o ha scoperto una soluzione alternativa? Perché la richiesta dovrebbe essere impostata diversamente quando viene visitata da un bot?

UPDATE: alcuni debug aggiuntivi hanno mostrato che HttpServerVarsCollection è stato eliminato, insieme al suo oggetto HttpRequest padre. La domanda ora è: come può essere esposto l'oggetto Request restituito da HttpContext.Current prima che la richiesta sia completa?

HttpServerVarsCollection.Get Metodo

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; 
} 

pila completa traccia

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' non deve essere stato eliminato prima del completamento della richiesta. Hai forse un codice che dice 'using (HttpContext.Current.Request)' o l'equivalente? –

+1

No ... quella era una delle poche cose a cui inizialmente pensavo. Ho esaminato tutto il codice che ho e nulla rende esplicita (o implicita attraverso l'uso) la chiamata a Dispose sull'oggetto richiesta. Ho tuttavia determinato attraverso più debug che si verifica solo in modalità integrata di IIS 7 - non nel classico o nel server di sviluppo ASP.NET. –

+0

In realtà ho confermato solo su IIS 7.5 o Windows 7 e 2008 R2. In realtà non ho testato IIs 7.0. –

risposta

1

So che questa domanda è piuttosto vecchio, ma di recente ho mi sono trovato in una situazione molto simile in cui la mia UrlHelper mi ha dato un'eccezione di riferimento null su System.Web.HttpServerVarsCollection.Get.

Il problema era davvero HTTP_X_ORIGINAL_URL e questa variabile particolare server viene dal URL Rewrite 2.0 Modulo su IIS.

È interessante notare che questo modulo è stato installato ma non utilizzato. Tuttavia, solo la sua presenza è stata sufficiente a causare il problema. Disinstallarlo ha reso l'errore andare via.

Se è necessario eseguire la riscrittura dell'URL, ci sono altri moduli disponibili oppure è possibile farlo a livello di applicazione.

Spero che questo aiuti.

3

Ho avuto questo problema, ma non era correlato ai moduli di riscrittura degli URL.

Nel mio caso, ho accidentalmente memorizzato nella cache un'istanza di UrlHelper in un campo statico e in seguito le richieste hanno rilevato un'istanza eliminata dalle richieste precedenti.

+0

probabilmente mi hai appena salvato una settimana di debug, grazie – AaronHS

1

Mi sono imbattuto in questo, nel mio caso è stato in grado di risolvere passando a un metodo non di estensione l'utilizzo di UrlHelper. Ho avuto un metodo di estensione che ne chiama un altro, ma passando UrlHelper al secondo metodo.

In questo modo è stato rotto:

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)); 
} 

In questo modo funziona:

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)); 
} 

Nota la funzione differenza firma del metodo patrimoniale.

Problemi correlati