Пустая ссылка исключение при генерации URL с методом UrlHelper.Action - PullRequest
17 голосов
/ 27 декабря 2011

По какой-то причине, когда определенные боты посещают сайт, генерация URL с помощью метода UrlHelper.Action вызывает нулевое исключение из System.Web.HttpServerVarsCollection.Get.Я выполнил некоторую отладку, и стек вызовов возник при попытке получить 'HTTP_X_ORIGINAL_URL' из коллекции HttpContextBase.Request.ServerVariables.

Если я захожу на тот же адрес напрямую из браузера - нет проблем.Страница является серверной, и ошибка не регистрируется.Кажется, это происходит только при посещении бота.

Не уверен, что это актуально или нет, но сайт был только что перенесен в IIS 7.5.По-прежнему используется .NET 2.0 в интегрированном режиме.

Глядя на код как обратный с помощью Reflector, единственное место, где в методе Get может возникнуть пустое исключение, - это вызов this._request.FetchServerVariables.Как будто полный запрос не был правильно настроен.

Кто-нибудь еще сталкивался с этой проблемой или обнаружил обходной путь?Почему запрос настраивается по-разному при посещении бота?

UPDATE : Некоторая дополнительная отладка показала, что HttpServerVarsCollection был уничтожен вместе с его родительским объектом HttpRequest.Теперь возникает вопрос - как можно представить объект Request, возвращенный HttpContext.Current до завершения запроса?

HttpServerVarsCollection.Get Method

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

Полная трассировка стека

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

Ответы [ 3 ]

3 голосов
/ 30 июля 2012

У меня была эта проблема, но она не была связана с модулями перезаписи URL.

В моем случае я случайно кэшировал экземпляр UrlHelper в статическом поле, и более поздние запросы столкнулись с удаленным экземпляром из предыдущих запросов.

1 голос
/ 01 ноября 2012

Я столкнулся с этим, в моем случае смог решить, переключившись на не-расширение метода использования UrlHelper. У меня был один метод расширения, вызывающий другой, но передающий UrlHelper второму методу.

Этот путь был сломан:

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

Так работает:

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

Обратите внимание на различие сигнатур функций метода Asset.

1 голос
/ 07 марта 2012

Я знаю, что этот вопрос довольно старый, но недавно я оказался в очень похожей ситуации, когда мой UrlHelper выдавал мне исключение нулевой ссылки на System.Web.HttpServerVarsCollection.Get.

Проблема действительно была HTTP_X_ORIGINAL_URL, и эта конкретная серверная переменная взята из модуля URL Rewrite 2.0 в IIS.

Интересно, что этот модуль был установлен, но не использовался. Однако только его присутствия было достаточно, чтобы вызвать проблему. При его удалении ошибка исчезла.

Если вам нужно перезаписать URL-адрес, существуют другие модули или вы можете сделать это на уровне приложения.

Надеюсь, это поможет.

...