title: HttpContext.Items with ASP.NET MVC
body: <p>I'm implimenting my own ApplicationContext class that uses the singleton pattern.  I want to store my instance of it in HttpContext.Items, since it is accessible in all parts of the request.  I've been reading about using HttpContext with ASP.NET MVC and one of the major pains is that it introduces testing complexity. I've tried doing research on the testability of HttpContext.Items, but all I can find is stuff on Session.  One of the only things I've found is out of a sample chapter in the Professional ASP.NET 3.5 MVC book on Wrox (<a href="http://media.wiley.com/assets/1539/15/professionalaspnet35mvc_chapter13.pdf" rel="noreferrer">pdf link here</a>).  On page 15 it says this:</p>
  
  <blockquote>
    <p><strong>Something You Can’t Use: HttpContext.Items</strong> <br/>
    Above in this section, we came clean and told you that we lied to you: HttpContext is not shared between ASP.NET MVC and ASP.NET Web Forms. As a result of this, you cannot use the HttpContext.Items collection to store and retrieve bits of data.<br/><br/>
    The reason for this is because once you redirect to a Controller, your HttpHandler becomes the System.Web.Mvc.MvcHandler, which is created using HttpContextWrapper, which will have its own definition of HttpContext.Current. Unfortunately, during this handshake, things like HttpContext.Items are not transferred.<br/><br/>
    What this boils down to is that the HttpContext types, despite looking and sounding very much the same, are not the same, and you cannot pass data in this way.</p>
  </blockquote>
  
  <p>Now, I've tried testing this out, and as far as I can tell, if you redirect to another controller using RedirectToAction, HttpContext.Items does remain.  I'm using the default ASP.NET MVC project to test this.  What I've done is, add this method to Global.asax.cs:</p>
  
  <pre><code>protected void Application_BeginRequest()
  {
      Context.Items["Test"] = "Hello World";
  }
  </code></pre>
  
  <p>And in HomeController.cs, I've changed the Index method to:</p>
  
  <pre><code>public ActionResult Index()
  {
      return RedirectToAction("About");
  }
  </code></pre>
  
  <p>And changed the About method to:</p>
  
  <pre><code>public ActionResult About()
  {
      Response.Write(Convert.ToString(HttpContext.Items["Test"]));
      return View();
  }
  </code></pre>
  
  <p>When I run the application, the page properly redirects to /Home/About and Response.Writes the correct "Hello World" string set in the global.asax.cs.  </p>
  
  <p>So, it seems to me as if I'm either not understanding what the book is meaning when they say 
   "things like HttpContext.Items are not transferred" OR it does transfer this stuff and it's okay to use HttpContext.Items.</p>
  
  <p>If you guys recommend that I avoid HttpContext.Items, is there another alternative way to store an object across a request on a per-request basis?</p>