Frage

Ich bin meine eigene Klasse Application implimenting, die das Singleton-Muster verwendet. Ich möchte, dass meine Instanz davon in HttpContext.Items speichern, da es in allen Teilen der Anfrage zugänglich ist. Ich habe gelesen, über die Verwendung von Httpcontext mit ASP.NET MVC und einer der großen Schmerzen ist, dass es Tests Komplexität führt. Ich habe versucht, auf der Prüfbarkeit HttpContext.Items forschen, aber alles, was ich finden kann, ist Sachen auf Session. Einer der wenigen Dinge, die ich gefunden habe, ist aus einer Probe Kapitel im Buch Professionelle ASP.NET 3.5 MVC auf Wrox ( pDF-Link hier ). Auf Seite 15 heißt es folgendermaßen aus:

  

etwas, das Sie nicht verwenden: HttpContext.Items
  Oben in diesem Abschnitt kamen wir sauber und gesagt, dass wir dich belogen: Httpcontext nicht zwischen ASP.NET MVC und ASP.NET Web Forms gemeinsam genutzt wird. Als Folge davon können Sie verwenden, um die HttpContext.Items Sammlung Bits von Daten zu speichern und abzurufen.
  Der Grund dafür ist, dass, wenn Sie in eine Steuerung umleiten, Ihre Httphandler den System.Web.Mvc.MvcHandler werden, die erstellt wird HttpContextWrapper, die ihre eigene Definition von HttpContext.Current hat. Leider während dieser Händedruck, Dinge wie HttpContext.Items werden nicht übertragen.
  Was dies läuft darauf hinaus, dass die Httpcontext-Typen, trotz ähnlichen und sehr viel die gleiche klingen, sind nicht die gleichen, und Sie können keine Daten auf diese Weise passieren.

Nun, ich habe versucht, die Prüfung dieses heraus, und soweit ich das beurteilen kann, wenn Sie auf einen anderen Controller verwenden RedirectToAction umleiten, HttpContext.Items bleibt. Ich bin mit dem Standard ASP.NET MVC-Projekt, dies zu testen. Was ich habe, ist getan, fügen Sie diese Methode Global.asax.cs:

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

Und in HomeController.cs, ich habe die Index-Methode geändert:

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

Und verändert die Über-Methode:

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

Wenn ich die Anwendung ausführen, die Seite umleitet richtig / Home / über und Response.Writes das richtige „Hallo Welt“ Zeichenfolge in dem global.asax.cs gesetzt.

So scheint es mir, als ob ich auch nicht verstehen, was das Buch Sinn, wenn sie sagen,  „Dinge wie HttpContext.Items werden nicht übertragen“ oder es ist das Zeug übertragen und es ist in Ordnung HttpContext.Items zu verwenden.

Wenn euch empfehlen, dass ich vermeiden HttpContext.Items, gibt es eine weitere alternative Möglichkeit, ein Objekt über eine Anforderung zum Speichern auf einem Pro-Anfrage und?

War es hilfreich?

Lösung

Ihre Frage ist, ein paar Dinge zu fragen, aber ich denke, Punkt 1 ist die Antwort, die Sie suchen.

  1. Ist es in Ordnung Context.Items für das Caching auf einer pro Anfrage und zu benutzen? Ja. Wenn in Prozess, pro Anfrage, pro Maschine in der Web-Farm Ihre Kriterien sind dann Context.Items gibt Ihnen das.

  2. Ist Context.Items schwierig zu testen, mit? Soweit Testbarkeit, würde ich Context.Items hinter einer Schnittstelle von einer Art verbergen. Auf diese Weise erhalten Sie Unit-Test-Funktionen ohne Context.Items direkt verweisen zu müssen. Ansonsten, was Sie brauchen über Context.Items zu testen? Dass der Rahmen speichert und Werte abrufen? Halten Sie Ihren Code unwissend System.Web und du wirst ein glücklicher Mensch sein.

  3. Wird Context.Items RedirectToAction überleben? Nein. Ihr Test ist ungültig. Es Einstellung „Hallo Welt“ auf jeder Web-Anfrage und Ihre Test erstreckt sich über zwei Web-Anfragen. Die erste ist, wenn der Index Aktion aufgerufen wird. Die zweite ist, wenn RedirectToAction Aktion aufgerufen wird (es ist ein HTTP 302). Damit es nicht, einen neuen Wert im Index Aktion und sehen, ob es in der über Aktion beibehalten wird.

Andere Tipps

Mit der TempData Wörterbuch, es ist vor allem für Objekte zwischen Aktionen Speicherung umleitet:

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

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

Dann den Wert Ihrer Ansicht abrufen:

<%=ViewData["Test"] %>

Ich habe einen Test und TempData hat, in der Tat, explodiert mit Sitzungsstatus deaktiviert. Mein einziger Rat wäre, nicht zu speichern das Objekt selbst in Temperaturdaten, sondern speichert die einfachen typisierte Felder wie vorgeschlagen. Da Sie nicht Gegenstand Bäume Serialisierung sollte es nicht sein, dass große einer Auswirkung auf die Leistung ausgeführt wird out-of-process.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top