Je travaille avec des outils WebForms/MVC-agnostic et il me faut une instance de HttpContext
avec une référence à un objet HttpContextBase
. Je ne peux pas utiliser HttpContext.Current
parce que j’ai besoin que cela fonctionne aussi de manière asynchrone (HttpContext.Current
retourne null
lors d’une requête asynchrone). Je suis au courant de HttpContextWrapper
, mais ça ne va pas.
Le moyen le plus simple est d’obtenir l’application, ApplicationInstance
, et d’utiliser sa Context
propriété:
// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;
(merci à Ishmael Smyrnow qui l'a noté dans les commentaires)
Vous pouvez le faire, surtout si l'instance HttpContextBase
qui vous a été transmise est de type HttpContextWrapper
au moment de l'exécution. L'exemple suivant montre comment procéder. Cela suppose que vous avez une méthode appelée Foo
qui accepte le contexte en tant que HttpContextBase
mais doit ensuite appeler une méthode dans une assemblée tierce (que vous n’aurez peut-être pas la chance de modifier) s'attendant à ce que le contexte soit saisi sous la forme 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
a une méthode appelée GetService
à la suite de la prise en charge de IServiceProvider
. Le remplacement GetService
des délégués HttpContextWrapper
à l'implémentation GetService
de l'instance encapsulée HttpContext
. L'implémentation GetService
de HttpContext
vous permet de rechercher des suspects habituels tels que HttpApplication
, HttpRequest
, HttpResponse
, etc. Il se trouve que HttpApplication
a une propriété appelée Context et qui renvoie une instance de HttpContext
. Donc, on obtient l'instance encapsulée HttpContext
en demandant à HttpContextBase
de HttpApplication
via GetService
, puis en lisant la propriété Context
du HttpApplication
instance.
Contrairement à HttpContextBase
, GetService
n'apparaît pas en tant que membre public de HttpContext
, mais c'est parce que HttpContext
implémente IServiceProvider.GetService
explicite tandis que HttpContextBase
ne le fait pas.
Gardez à l'esprit que Foo
n'est plus testable car il repose sur le fait de pouvoir décompresser le sous-jacent HttpContext
sous-jacent pendant les tests et qu'il est pratiquement impossible de simuler/stub en premier lieu. Le but de cette réponse est toutefois de répondre à la question "Comment obtenir un objet HttpContext à partir de HttpContextBase?", littéralement . La technique illustrée est utile dans les situations où vous vous trouvez pris en sandwich entre des composants que vous n’avez pas nécessairement le luxe de modifier.
Vous pouvez,
var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
Tu ne peux pas.
Le but de HttpContextBase
est d’abstraire la dépendance à la classe concrète HttpContext
. Bien que puisse contenir un HttpContext
concret (comme dans le cas de httpContextWrapper
) , d'autres implémentations peuvent n'avoir absolument rien à voir avec HttpContext
.
Votre meilleure option est de définir une fabrique abstraite personnalisée pouvant obtenir un HttpContextBase
, car vous pouvez toujours envelopper un HttpContext
dans un HttpContextWrapper
.