2011-12-27 29 views
15

Vì một số lý do, khi một số bot truy cập trang web, tạo url với phương thức UrlHelper.Action sẽ tăng ngoại lệ null từ System.Web.HttpServerVarsCollection.Get. Tôi đã thực hiện một số gỡ lỗi và cuộc gọi ngăn xếp originiates với một nỗ lực để có được 'HTTP_X_ORIGINAL_URL' từ bộ sưu tập HttpContextBase.Request.ServerVariables.Ngoại lệ tham chiếu Null khi tạo url bằng phương thức UrlHelper.Action

Nếu tôi truy cập cùng một địa chỉ trực tiếp từ trình duyệt - không sao cả. Trang này là máy chủ và không có lỗi nào được ghi lại. Nó dường như chỉ xảy ra khi một bot truy cập.

Bạn không chắc chắn nó có liên quan hay không, nhưng trang web vừa được di chuyển sang IIS 7.5. Vẫn đang sử dụng .NET 2.0 ở chế độ Tích hợp.

Nhìn vào mã được đảo ngược bởi Reflector nơi duy nhất có ngoại lệ null có thể xảy ra trực tiếp trong phương thức Get là cuộc gọi đến this._request.FetchServerVariables. Như thể yêu cầu hoàn chỉnh không được thiết lập đúng cách.

Có ai khác phải đối mặt với vấn đề này hoặc phát hiện ra giải pháp thay thế không? Tại sao yêu cầu sẽ được thiết lập khác khi được bot truy cập?

CẬP NHẬT: Một số gỡ lỗi bổ sung đã chỉ ra rằng HttpServerVarsCollection đã được xử lý, cùng với đối tượng HttpRequest cha mẹ của nó. Câu hỏi bây giờ là - làm thế nào để đối tượng Request được trả về bởi HttpContext.Current được tiếp xúc trước khi yêu cầu hoàn tất?

HttpServerVarsCollection.Get Phương pháp

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

Full stack trace

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' không được xử lý trước khi yêu cầu hoàn tất. Bạn có thể có mã mà nói 'sử dụng (HttpContext.Current.Request)' hoặc tương đương? –

+1

Không ... đó là một trong số ít những điều tôi nghĩ ban đầu. Tôi đã xem xét tất cả các mã mà tôi có và không có gì làm cho một rõ ràng (hoặc ngầm thông qua sử dụng) gọi để Vứt bỏ trên đối tượng yêu cầu. Tuy nhiên tôi đã xác định thông qua gỡ lỗi nhiều hơn rằng nó chỉ xảy ra trong chế độ tích hợp IIS 7 - không phải trong cổ điển hoặc trong máy chủ phát triển ASP.NET. –

+0

Thực ra tôi chỉ xác nhận trong IIS 7.5 o Windows 7 & 2008 R2. Chưa thực sự thử nghiệm IIs 7.0. –

Trả lời

1

Tôi biết câu hỏi này là khá cũ bây giờ, nhưng thời gian gần đây tôi thấy mình trong một tình huống rất giống nơi tôi UrlHelper đã cho tôi ngoại lệ tham chiếu null trên System.Web.HttpServerVarsCollection.Get là tốt.

Vấn đề thực sự là HTTP_X_ORIGINAL_URL và biến máy chủ cụ thể này xuất phát từ mô-đun URL Rewrite 2.0 trên IIS.

Điều thú vị là đủ mô-đun này đã được cài đặt nhưng không được sử dụng. Tuy nhiên, chỉ có sự hiện diện của nó là đủ để gây ra vấn đề. Gỡ cài đặt nó đã khiến lỗi biến mất.

Nếu bạn cần ghi lại URL, có các mô-đun khác ngoài đó hoặc bạn có thể thực hiện ở cấp ứng dụng.

Hy vọng điều đó sẽ hữu ích.

3

Tôi gặp sự cố này nhưng không liên quan đến mô-đun viết lại URL.

Trong trường hợp của tôi, tôi vô tình lưu trong bộ nhớ cache một thể hiện của UrlHelper trong một trường tĩnh và các yêu cầu sau đó gặp phải một cá thể được xử lý từ các yêu cầu trước đó.

+0

điều này có thể vừa lưu tôi một tuần gỡ lỗi, cảm ơn bạn – AaronHS

1

Tôi gặp phải vấn đề này, trong trường hợp của tôi có thể giải quyết bằng cách chuyển sang sử dụng phương pháp không mở rộng của UrlHelper. Tôi đã có một phương pháp mở rộng gọi một phương thức khác, nhưng chuyển UrlHelper sang phương thức thứ 2.

Bằng cách này đã bị hỏng:

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

Bằng cách này hoạt động:

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

Lưu ý sự khác biệt chữ ký chức năng của phương pháp tài sản.

Các vấn đề liên quan