Как получить объект HttpContext из HttpContextBase в ASP.NET MVC 1?

Я работаю с некоторыми инструментами WebForms/MVC-agnostic, и мне нужно получить экземпляр HttpContext с ссылкой на объект HttpContextBase. Я не могу использовать HttpContext.Current, потому что мне тоже нужно работать асинхронно (HttpContext.Current возвращает null во время асинхронного запроса). Я знаю HttpContextWrapper, но идет не так.

Ответ 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.