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