Я работаю с некоторыми инструментами WebForms/MVC-agnostic, и мне нужно получить экземпляр HttpContext
с ссылкой на объект HttpContextBase
. Я не могу использовать HttpContext.Current
, потому что мне тоже нужно работать асинхронно (HttpContext.Current
возвращает null
во время асинхронного запроса). Я знаю HttpContextWrapper
, но идет не так.
Как получить объект HttpContext из HttpContextBase в ASP.NET MVC 1?
Ответ 1
Самый простой способ - получить приложение ApplicationInstance
и использовать его Context
свойство:
// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;
(спасибо Измаил Смирнов, который отметил это в комментариях)
Оригинальный ответ:
Вы можете, особенно если экземпляр HttpContextBase
, который вы передали, имеет тип HttpContextWrapper
во время выполнения. Следующий пример иллюстрирует, как вы можете это сделать. Предполагается, что у вас есть метод под названием Foo
, который принимает контекст как HttpContextBase
, но затем ему нужно вызвать метод в сторонней сборке (для которой вам может не пригодиться удача), который ожидает, что контекст будет введен как HttpContext
.
void Foo(HttpContextBase context)
{
var app = (HttpApplication) context.GetService(typeof(HttpApplication));
ThirdParty.Bar.Baz(app.Context);
}
// Somewhere in assembly and namespace ThirdParty,
// in a class called Bar, there is Baz expecting HttpContext:
static void Baz(HttpContext context) { /* ... */ }
HttpContextBase
имеет метод GetService
в результате поддержки IServiceProvider
. Обозначение GetService
HttpContextWrapper
делегирует реализацию GetService
обернутого экземпляра HttpContext
. Реализация GetService
HttpContext
позволяет запросить обычных подозреваемых, таких как HttpApplication
, HttpRequest
, HttpResponse
и так далее. Так получилось, что HttpApplication
имеет свойство Context и возвращает экземпляр HttpContext
. Таким образом, можно получить экземпляр HttpContext
, запросив HttpContextBase
для HttpApplication
через GetService
, а затем прочитав свойство Context
возвращаемого экземпляра HttpApplication
.
В отличие от HttpContextBase
, GetService
не отображается как открытый член HttpContext
, но это связано с тем, что HttpContext
реализует IServiceProvider.GetService
разницу, а HttpContextBase
не работает.
Имейте в виду, что Foo
больше не тестируется, потому что он полагается на возможность развернуть базовый HttpContext
во время тестирования и который практически невозможно подделать/заглушить в первую очередь. Однако точка этого ответа заключается в том, чтобы в буквальном смысле решить вопрос "Как получить объект HttpContext из HttpContextBase?". Иллюстрированный метод полезен в тех ситуациях, когда вы обнаруживаете, что вы зажаты между компонентами, которые вы не обязательно должны модифицировать.
Ответ 2
Вы можете,
var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
Ответ 3
Вы не можете.
Цель HttpContextBase
состоит в том, чтобы абстрагировать зависимость от конкретного класса HttpContext
. Хотя он может содержать конкретный HttpContext
(например, с httpContextWrapper
), другие реализации могут не иметь абсолютно никакого отношения к HttpContext
.
Ваш лучший вариант - определить пользовательский абстрактный Factory, который может получить HttpContextBase
для вас, так как вы всегда можете обернуть конкретный HttpContext
в httpContextWrapper
.