web-dev-qa-db-fra.com

Comment obtenir un objet HttpContext auprès de HttpContextBase dans ASP.NET MVC 1?

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.

148
Daniel Schaffer

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)

Réponse originale:

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.

237
Atif Aziz

Vous pouvez,

var abstractContext = new System.Web.HttpContextWrapper(System.Web.HttpContext.Current);
30
Marc Chouteau

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.

14
Mark Seemann