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
'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? –
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. –
In realtà ho confermato solo su IIS 7.5 o Windows 7 e 2008 R2. In realtà non ho testato IIs 7.0. –