Question

J'implimenting ma propre classe ApplicationContext qui utilise le pattern singleton. Je veux conserver mon exemple de celui-ci dans HttpContext.Items, car il est accessible dans toutes les parties de la demande. J'ai lu sur l'utilisation HttpContext avec ASP.NET MVC et l'une des principales douleurs est qu'il introduit la complexité des tests. J'ai essayé de faire des recherches sur la testabilité de HttpContext.Items, mais tout ce que je peux trouver est une chose sur session. L'une des seules choses que je connaisse est celui d'un chapitre de l'échantillon dans le Professional ASP.NET MVC 3.5 livre sur Wrox ( lien pdf ). A la page 15, il dit ceci:

  

Quelque chose vous ne pouvez pas utiliser: HttpContext.Items   Au-dessus de cette section, nous vous sommes propre et dit que nous vous a menti: HttpContext n'est pas partagé entre ASP.NET MVC et ASP.NET Web Forms. En raison de cela, vous ne pouvez pas utiliser la collection HttpContext.Items pour stocker et récupérer des morceaux de données.
  La raison de cela est parce qu'une fois que vous redirigez à un contrôleur, votre HttpHandler devient le System.Web.Mvc.MvcHandler, qui est créée en utilisant HttpContextWrapper, qui aura sa propre définition de HttpContext.Current. Malheureusement, au cours de cette poignée de main, des choses comme HttpContext.Items ne sont pas transférés.
  Ce que cela se résume à dire que les types de HttpContext, en dépit recherche et de sondage très bien même, ne sont pas les mêmes, et vous ne pouvez pas transmettre des données de cette façon.

Maintenant, je l'ai essayé de tester ceci, et pour autant que je peux dire, si vous rediriger vers un autre contrôleur en utilisant RedirectToAction, HttpContext.Items ne reste. J'utilise le projet par défaut ASP.NET MVC pour tester. Ce que je l'ai fait est, ajouter cette méthode pour Global.asax.cs:

protected void Application_BeginRequest()
{
    Context.Items["Test"] = "Hello World";
}

Et dans HomeController.cs, j'ai changé la méthode Index:

public ActionResult Index()
{
    return RedirectToAction("About");
}

Et changé la méthode A propos de:

public ActionResult About()
{
    Response.Write(Convert.ToString(HttpContext.Items["Test"]));
    return View();
}

Quand je lance l'application, la page réoriente correctement / Accueil / A propos et Response.Writes la bonne chaîne « Bonjour tout le monde » situé dans les Global.asax.cs.

Alors, il me semble que si je ne comprends pas non plus ce que le livre est le sens quand ils disent  « Les choses comme HttpContext.Items ne sont pas transférés » ou il ne transfère ce genre de choses et il est acceptable d'utiliser HttpContext.Items.

Si vous les gars que je recommande éviter HttpContext.Items, est-il une autre alternative pour stocker un objet à travers une demande sur une base par demande?

Était-ce utile?

La solution

Votre question pose un certain nombre de choses, mais je pense que le point 1 est la réponse que vous recherchez.

  1. Est-il bon d'utiliser Context.Items pour la mise en cache sur une base par demande? Oui. Si en cours, par demande, par machine dans la batterie de serveurs Web est à vos critères puis Context.Items vous donne cela.

  2. est difficile Context.Items à tester avec? En ce qui concerne la testabilité, je me cachais derrière Context.Items une interface de quelque sorte. De cette façon, vous obtenez des capacités de tests unitaires sans faire référence Context.Items directement. Sinon, qu'est-ce que vous avez besoin de tester sur les Context.Items? Que le cadre stocker et récupérer des valeurs? Gardez votre code ignorant System.Web et vous serez un campeur heureux.

  3. Est-ce que Context.Items survivre RedirectToAction? Non. Votre test est invalide. Il est le réglage « Bonjour, monde » à chaque requête web et votre test couvre deux requêtes Web. La première est lorsque l'action index est appelée. Le second est lorsque l'action de RedirectToAction est appelé (c'est un HTTP 302). Pour le faire échouer, définir une nouvelle valeur dans l'action Index et voir si elle est retenue dans l'action A propos.

Autres conseils

Utilisez le TempData Dictionnaire, il est principalement pour le stockage d'objets entre les actions réoriente:

public ActionResult Index()
{
    TempData.Add("Test", "Hello world");
    return RedirectToAction("About");
}

public ActionResult About()
{
    ViewData["Test"] = TempData["Test"];
    return View();
}

Ensuite, récupérer la valeur de votre point de vue:

<%=ViewData["Test"] %>

Je l'ai fait un test et TempData ne, en effet, avec l'état de exploserai séance désactivé. Mon seul conseil serait de ne pas stocker l'objet lui-même dans les données temporaires, mais stocker les simples champs typés comme cela a été suggéré. Puisque vous n'êtes pas sérialisation arbres objet, il ne devrait pas être un gros impact sur les performances en cours d'exécution hors processus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top