HttpContext sur les instances de contrôleurs sont null dans ASP.net MVC
Ce n'est peut-être pas la bonne façon d'utiliser les contrôleurs, mais j'ai remarqué ce problème et je n'avais pas trouvé un moyen de le corriger.
public JsonResult SomeControllerAction() {
//The current method has the HttpContext just fine
bool currentIsNotNull = (this.HttpContext == null); //which is false
//creating a new instance of another controller
SomeOtherController controller = new SomeOtherController();
bool isNull = (controller.HttpContext == null); // which is true
//The actual HttpContext is fine in both
bool notNull = (System.Web.HttpContext.Current == null); // which is false
}
J'ai remarqué que le HttpContext sur un contrôleur n'est pas le HttpContext "réel" que vous trouverez dans le système.Web.HttpContext.Actuel.
Existe-t-il un moyen de remplir manuellement HttpContextBase sur un contrôleur? Ou une meilleure façon de créer une instance d'un Contrôleur?
5 réponses
Les contrôleurs ne sont pas conçus pour être créés manuellement comme vous le faites. Il semble que ce que vous devriez vraiment faire est de mettre n'importe quelle logique réutilisable que vous avez dans une classe d'aide à la place.
Pour l'instant, je vais faire ce qui suit. Cela semble être une solution acceptable correctif...
public new HttpContextBase HttpContext {
get {
HttpContextWrapper context =
new HttpContextWrapper(System.Web.HttpContext.Current);
return (HttpContextBase)context;
}
}
Lorsque ceci est ajouté à une classe de contrôleur dont ces contrôleurs héritent.
Je ne suis pas sûr si le HttpContext étant null est le comportement désiré, mais cela le corrigera en attendant pour moi.
Le HttpContext, dans ControllerContext est null car il n'est pas défini lors de la création du contrôleur. Le contructor du contrôleur n'attribue pas cette propriété, il sera donc null. Normalement, HttpContext est défini sur HttpContext de la classe ControllerBuilder. Les contrôleurs sont créés par la classe ControllerBuilder, suivie de DefaultControllerFactory. Lorsque vous souhaitez créer votre propre instance d'un contrôleur, vous pouvez utiliser la méthode D'exécution du contrôleur avec la vôtre ControllerContext. Vous ne voulez pas faire cela est une application réelle. Lorsque vous obtenez plus d'expérience avec le cadre, vous trouverez la méthode appropriée pour faire ce que vous voulez. Lorsque vous avez besoin de ControllerContext dans le test unitaire, vous pouvez utiliser un framework moqueur pour simuler le ControllerContext ou vous pouvez le simuler par classe.
Vous pouvez trouver un modèle du flux de requête dans asp.net mvc sur ce blog .
Lorsque votre nouveau à Asp.net mvc, ça vaut le coup de télécharger le code source et lire une trace de la route comment une demande est traitée.
Est-ce que vous voulez utiliser certaines fonctionnalités du contrôleur? Ou le contrôleur effectue-t-il une action?
Si c'est le premier, peut-être que c'est un code qui devrait être divisé en une autre classe. Si c'est le dernier, vous pouvez le faire pour simplement que ce contrôleur fasse une action spécifique:
return RedirectToAction("SomeAction", "SomeOtherController", new {param1 = "Something" });
Utilisez - vous une usine de contrôleurs? Si oui, comment enregistrez-vous les composants?
J'ai rencontré ce problème où j'avais ajouté par inadvertance une dépendance basée sur HttpContext en tant que Singleton, plutôt que transitoire dans Windsor.
HttpContext était null pour toutes les requêtes sauf la première. Il m'a fallu un certain temps pour retracer un.