若是ASP.NET程序以IIS集成模式運行,在Global.asax的Application_Start()中,只要訪問Context.Request,好比下面的代碼服務器
var request = Context.Request;ide
就會引起異常:this
Request is not available in this context日誌
不信你能夠試試。blog
這個問題只會出如今IIS集成模式(Integrated),若是改成傳統模式(Classic),問題就不會出現。部署
今天就被這個問題小小折騰了一下。咱們在錯誤日誌模塊中增長了記錄當前訪問網址的操做,這樣,發生錯誤時,咱們能夠準確地知道引起錯誤的訪問網址。咱們添加了下面這樣的get
代碼:string
HttpContext context = HttpContext.Current;
if (context != null && context.Request != null && context.Request.Url != null)
{
return context.Request.Url.AbsoluteUri;
}io
而後將更新的日誌模塊部署到服務器上,在一個應用中卻出現「Request is not available in this context」異常,以下圖:request
從上面的異常信息能夠看出,異常發生於在Application_Start中訪問HttpContext的Request屬性時(該應用在Application_Start進行了日誌記錄操做,因此訪問了HttpContext.Request)。
用ILSpy查看HttpContext的
代碼:
internal bool HideRequestResponse;
public HttpRequest Request
{
get
{
if (this.HideRequestResponse)
{
throw new HttpException(SR.GetString("Request_not_available"));
}
return this._request;
}
}
能夠看出,這個異常是在HideRequestResponse == true時扔出的,也就是說在Application_Start階段,HideRequestResponse的值是true。
讓人困惑的地方是既然在HideRequestResponse == true時不容許訪問Request屬性,那HttpContext爲何不提供一種方式讓調用者知道——「此時嚴禁調用Request」。若是調用者調用前能夠檢查一下相關規定,就不用這麼既浪費感情,又要付出代價(捕獲這個HttpException)。
另外,咱們的需求只是想獲得當前請求的URL,不能訪問Request,咱們就不能獲得這個URL。難道在Application_Start時就不能獲得當前請求的URL,這個URL是從外部(IIS)傳遞給ASP.NET Runtime的,與ASP.NET Runtime的狀態根本無關,有點想不通。。。
無奈,只能將就着先把問題解決,經過捕獲異常進行判斷,
代碼以下:
HttpContext context = HttpContext.Current; if (context != null && context.Request != null && context.Request.Url != null) { try { return context.Request.Url.AbsoluteUri; } catch (Exception ex) { if (ex is HttpException) { return string.Empty; } } }