环境:
Windows 2008, VS 2008 SP1, Asp.Net Mvc 1.0
------------------------------------------------------------------------------
一. 在Asp.Net Mvc应用程序中禁用SessionState
在Asp.Net Mvc: 浅析TempData机制一文中,我们简单探讨了Asp.Net Mvc中TempData的实现机制,由此得知默认情况下,TempData的DataProvider实现为基于Session的存储方式。
采用Session作为默认的数据存储方式,原本合情合理,只是,有时候,我们的网站中却不允许使用Session,需要禁用这家伙,如果这时候你只是简单的在Web.config中加上SessionState的禁用配置,就OK了吗?当然不是!
来看看情况吧:
给Web.config加上<sessionState mode="Off" />,然后运行程序,页面上马上会报告一个异常:
原因很简单,根据前文分析,无论如何,每次Action执行的时候都会Load和Save TempData,而此时如果我们禁用了Session,那么就必然出现上述异常。
那现在怎么办呢?其实,我甚至都不想在我的应用程序中使用TempData,我只是想禁用SessionState,然道,我要为此去实现另外一套TempDataProvider吗?代价是不是太高了?刚才说了,其实我压根儿都不想使用TempData,那么我为何不干脆实现一个啥事也不干的TempDataProvider得了。
二. 自定义一个NullTempDataProvider
嗯,现在就来写一个啥事也不干的TempDataProvider:
正如你看到的,NullTempDataProvider确实啥也没干,就是说,你写了貌似TempData["name"] = "Tristan"之类的语句等于白写,但前面说了,我不用TempData,所以,是可以接受的。
好了,替代品写好了,现在就要考虑怎么替代掉那个默认的SessionTempDataProvider了。
三. 全局应用NullTempDataProvider
方法 1. 通过创建Controller基类
请继续参考前文,可以得知TempDataProvider是在System.Web.Mvc.Controller中定义的,于是很容易想到,创建一个我们自己的所有Controller的基类,来指定默认的TempDataProvider。
在MyControllerBase的构造器中,指定TempDataProvider为NullTempDataProvider的一个实例。然后让我们其它的所有Controller都继承自MyControllerBase。嗯,运行后发现异常没有了,很顺利。
可是,引入一个新的Controller的基类是有代价的,如果我事先已经写了N个Controller了,那要改死了,能不能在某处轻松控制一下下就好了呢?
方法 2. 通过创建ControllFactory
Asp.Net Mvc生来就是易于扩展的,我们就是要在Controller中动一小下而已,于是想到在ControllerFactory上下功夫,何不自定义一个ControllerFactory来设置TempDataProvider呢:
MyControllerFactory继承自DefaultControllerFactory,然后override了CreateController()方法,在该方法里面增加了对TempDataProvider的赋值。接下来要做的事情,就是简单的在Global.ascx中注册一下这个ControllerFactory就可以了:
完成了,运行结果与预期一致,禁用了SessionState,实现了NullTempDataProvider,只是必须注意,TempData就不能用了。