I know what you're thinking...“Too many posts! He's mad! He's beating the pants off of Jenkies!“ Well, this one's technical.
If you're like me, you've always been annoyed at the inherent coupling between pages that pass data to each other through a Server.Transfer() call. I think it leads to poorly designed, tightly-coupled workflows, and tends to lead people to taking shortcuts or breaking the model to make their stuff work.
Until now, I've tried to minimize this issue by giving my base class page a TransferData property typed as an object so every page can use it to pass data. This has its own problems. For instance, if you call Server.Transfer twice in the same Request and use Context.Handler to retrieve the transferer (which seems like a hack to me), it's the first page, and there's not a reference to the second page in the call chain.
I now have discovered a nifty little storage location for putting things like this... HttpContext.Items. It's just an IDictionary that stores stuff in the context of the current request. Since you can always get the current HttpContext with HttpContext.Current (an implementation worth taking a look at with Reflector), you can get to it from anywhere, regardless of whether you have a reference to ANY page. It works even if you're passing control to or from some handler that's not even a page.
Think of it as the analog to Application state, or Session state, but for the current Request only. It automatically decouples your pages because they only have to agree on a common key.
UPDATE: I should note that it was my co-worker Casey Marshall who initially brought the property to my attention. Thanks, Casey