Domanda

Sono implimenting mia classe ApplicationContext che utilizza il pattern Singleton. Voglio conservare la mia istanza di esso in HttpContext.Items, dal momento che è accessibile in tutte le parti della richiesta. Ho letto su come utilizzare HttpContext con ASP.NET MVC e uno dei maggiori dolori è che introduce il test complessità. Ho provato a fare ricerche sulla verificabilità delle HttpContext.Items, ma tutto quello che posso trovare è roba sulla sessione. Una delle uniche cose che ho trovato è fuori di un capitolo di esempio nella MVC libro professionale ASP.NET 3.5 su Wrox (). A pagina 15 si legge questo:

  

Qualcosa Non è possibile utilizzare: HttpContext.Items
  Sopra in questa sezione, siamo venuti pulita e si detto che abbiamo mentito a voi: HttpContext non è condivisa tra ASP.NET MVC e ASP.NET Web Forms. Come risultato di questo, non è possibile utilizzare la collezione HttpContext.Items per memorizzare e recuperare bit di dati.
  La ragione di questo è perché una volta che si reindirizzare a un controller, la tua HttpHandler diventa lo System.Web.Mvc.MvcHandler, che viene creata usando HttpContextWrapper, che avrà la sua propria definizione di HttpContext.Current. Purtroppo, in questa stretta di mano, le cose come HttpContext.Items non sono trasferiti.
  Che questo si riduce a è che i tipi HttpContext, nonostante la ricerca e dal suono molto lo stesso, non sono gli stessi, e non è possibile passare i dati in questo modo.

Ora, ho provato a testare questo fuori, e per quanto posso dire, se si reindirizza a un altro controller utilizzando RedirectToAction, HttpContext.Items non rimangono. Sto usando il progetto di default ASP.NET MVC per testare questo. Quello che ho fatto è, aggiungere questo metodo per Global.asax.cs:

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

E in HomeController.cs, ho cambiato il metodo Index a:

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

E cambiato il metodo A proposito di:

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

Quando eseguo l'applicazione, la pagina reindirizza correttamente / Home / Chi e Response.Writes la corretta stringa "Ciao Mondo" impostato nelle global.asax.cs.

Quindi, mi sembra come se sto o non capire ciò che il libro è significato quando dicono  "Le cose come HttpContext.Items non vengono trasferiti" O lo fa trasferire questa roba ed è bene utilizzare HttpContext.Items.

Se voi ragazzi consiglia di evito HttpContext.Items, c'è un altro modo alternativo per memorizzare un oggetto attraverso una richiesta su una base per-request?

È stato utile?

Soluzione

La tua domanda sta chiedendo alcune cose, ma penso voce # 1 è la risposta che state cercando.

  1. E 'bene usare Context.Items per la cache su una base per ogni richiesta? Sì. Se nel processo, per ogni richiesta, per ogni macchina nella web farm è ai suoi criteri di allora Context.Items dà quella.

  2. È Context.Items difficile da provare con? Per quanto riguarda la verificabilità, mi nascondevo dietro Context.Items un'interfaccia di qualche tipo. In questo modo si ottiene capacità di test unità senza dover fare riferimento direttamente Context.Items. In caso contrario, che cosa è necessario testare su Context.Items? Che il quadro sarà memorizzare e recuperare i valori? Mantenete il vostro codice di ignoranti della System.Web e sarai un camper felice.

  3. Sarà Context.Items sopravvivere RedirectToAction? No. Il test non è valido. E 'l'impostazione "Ciao, mondo", a ogni richiesta web e il test si estende su due richieste web. Il primo è quando viene chiamato l'azione Index. Il secondo è quando viene chiamata azione RedirectToAction (è un HTTP 302). Per farla fallire, impostare un nuovo valore nell'azione Index e vedere se è trattenuto nel proposito di azione.

Altri suggerimenti

usare il dizionario TempData, è soprattutto per la memorizzazione di oggetti tra le azioni reindirizza:

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

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

Poi recuperare il valore nella vista:

<%=ViewData["Test"] %>

Ho fatto una prova e TempData fa, infatti, esplodo con lo stato della sessione disabilitato. Il mio unico consiglio è di non memorizzare l'oggetto in sé nei dati temporanei, ma memorizzare i semplici campi tipizzati come è stato suggerito. Dal momento che non sei serializzazione alberi di oggetti non dovrebbe essere così grande di un impatto sulle prestazioni in esecuzione out-of-process.

scroll top