Ответ 1
Это невозможно без использования отражения
Итак HttpContext.Request выдает, если вызывается в глобальном запуске
public HttpRequest get_Request()
{
if (this.HideRequestResponse)
{
throw new HttpException(SR.GetString("Request_not_available"));
}
return this._request;
}
Это фактически документировано
ASP.NET генерирует исключение, если вы попытаетесь использовать это свойство, когда объект HttpRequest недоступен. Например, это было бы верно в методе Application_Start файла Global.asax или в методе, который вызывается из метода Application_Start. В то время HTTP-запрос еще не создан.
Есть ли способ проверить, находится ли HttpContext.Request в состоянии, которое может быть извлечено без исключения исключения? Эффективно я хочу написать вспомогательный метод TryGetRequest
.
Это невозможно без использования отражения
Как видно из практики, это разумно и на самом деле может быть необходимо полагаться на жизненный цикл приложения ASP.NET, чтобы определить, когда появился текущий HttpRequest. Общий код регистрации, по-видимому, зависит, по крайней мере, от HttpContext.Current
или некоторой другой ссылки на текущий экземпляр HttpContext
. Если это предположение верно, тогда может быть реализована функция HttpModule
, которая хранит флаг в коллекции HttpContext.Items
при срабатывании события BeginRequest
. Статический TryGetRequest
вспомогательный метод может проверить наличие этого флага, чтобы определить, можно ли использовать HttpContext.Request
.
Возможно, так:
public class HttpRequestHelper : IHttpModule
{
private const string HttpRequestIsAvailable = "HttpRequestIsAvailable";
public static bool TryGetRequest(HttpContext context, out HttpRequest request)
{
request = null;
if (context != null)
{
if (context.Items.Contains(HttpRequestIsAvailable))
request = context.Request;
}
return (request != null);
}
#region IHttpModule
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += context_BeginRequest;
}
private void context_BeginRequest(object sender, EventArgs e)
{
((HttpApplication)sender).Context.Items.Add(HttpRequestIsAvailable, true);
}
#endregion
}
Модуль должен быть зарегистрирован в web.config(предполагая интегрированный конвейер IIS 7.0):
<system.webServer>
<modules>
<add name="HttpRequestHelper" type="Utility.HttpRequestHelper" />
</modules>
</system.webServer>
Код ведения журнала будет использовать вспомогательный метод следующим образом:
HttpRequest request;
if (HttpRequestHelper.TryGetRequest(HttpContext.Current, out request))
LogWithRequest(request, message);
else
LogWithoutRequest(message);
Реализация не зависит от частного API или отражения. Он опирается на флаг, но информация о состоянии остается с экземпляром HttpContext
и хорошо инкапсулирована.
Почему бы не перевести вызов на HttpContext.Request
с помощью блока try, catch, вы можете поймать исключение и соответствующим образом изменить свое поведение.