仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 873|回复: 8
打印 上一主题 下一主题

[学习教程] NET网页编程之浅谈ASP.NET MVC中TempData的完成机制

[复制链接]
金色的骷髅 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 14:26:35 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
实不相瞒,Java是我见过的执行效率最低的程序设计语言,前不久在CSDN论坛上有个评测,计算9999的阶乘,同样的循环算法,Java的耗时是.NET的5倍。本篇次要会商ASP.NETMVC中TempData是怎样完成的,经由过程研读MVC的源代码你将分明的懂得MVC是怎样完成TempData功效的。</P>TempData特征
TempDataDictionary与ITempDataProvider
TempDataDictionary的计划
SessionStateTempDataProvider与ITempDataProvider
TempData特征Top
TempData的特征就是能够在两个Action之间传送数据,它会保留一份数据到下一个Action,并跟着再下一个Action的到来而生效。以是它被用在两个Action之间来保留数据,好比,如许一个场景,你的一个Action承受一些post的数据,然后交给另外一个Action来处置,并显现到页面,这时候就能够利用TempData来传送这份数据。
那究竟TempData是如何完成这个功效的呢?上面我们从MVC的源代码动手来剖析TempData的机制。
TempDataDictionary与ITempDataProviderTop
起首来看看ITempDataProvider接口,从字面意义上看我们先把它翻译为:临时数据的供应者所服从的划定规矩,它商定了两个办法:
publicinterfaceITempDataProvider{
IDictionaryLoadTempData(ControllerContextcontrollerContext);
voidSaveTempData(ControllerContextcontrollerContext,IDictionaryvalues);
}
这两个办法是LoadTempData和SaveTempData,我们料想这两个办法是用来获得TempData容器和保留TempData数据的,由于LoadTempData前往一个IDictionary范例,而SaveTempData没有前往范例,而参数ControllerContext就是针对分歧的用户高低文来计划的,标明是对那一个高低文的TempData举行操纵。切实其实是如许的,前面会考证我们的料想。
再来看看TempDataDictionary,我们对这个类的第一印象在那里呢?是在ControllerBase类中的TempData属性,在一般的Controller中我们打上tempdata,vs匡助我们完成的谁人属性实在就是ControllerBase类中的TempData。因而我们分明了,不论是在controller中,仍是在view中,一切对TempData的操纵都是对TempDataDictionary范例的操纵。那ITempDataProvider有是怎样与TempDataDictionary接洽的呢?看一下TempDataDictionary的计划便一览无余。
TempDataDictionary的计划Top
publicclassTempDataDictionary:IDictionary<string,object>,ISerializable
这是TempDataDictionary的署名,我们看到它承继了一个IDictionary<string,object>的字典范例和一个ISerializable的接口。因而我们晓得它是能够被序列化和反序列化的,该类有一个常字符串范例的字段和一个Dictionary<string,object>范例的字段:
internalconststring_tempDataSerializationKey="__tempData";
internalDictionary<string,object>_data;
在它带参的机关函数中发明了对_tempDataSerializationKey的利用:
protectedTempDataDictionary(SerializationInfoinfo,StreamingContextcontext){
_initialKeys=newHashSet<string>(StringComparer.OrdinalIgnoreCase);
_modifiedKeys=newHashSet<string>(StringComparer.OrdinalIgnoreCase);
_data=info.GetValue(_tempDataSerializationKey,typeof(Dictionary<string,object>))
asDictionary<string,object>;
}
我们能够看到这是用来从一个流中,反序列化失掉一个Dictionary范例的历程。
另外一点,在controller中,我们能够如许利用TempData的:
TempData["msg"]=newObject();
Objectobj=TempData["msg"]asobject;
在懂得它的索引器之前我们先看看它的几个字段和办法,TempDataDictionary类主要的字段有三个:
internalDictionary<string,object>_data;
privateHashSet<string>_initialKeys;
privateHashSet<string>_modifiedKeys;
_data用来寄存真实的数据,_initialKeys用来寄存本来数据的key,_modifiedKeys用来寄存修正过或新增加的数据key。为何要如许呢?回忆一下TempData的特征,TempData只寄存一次数据,到第三个Action时,第一个Action寄存的数据就生效了,以是,_initialKeys被计划来寄存那些数据是本来的,_modifiedKeys被计划来寄存那些数据是修正过的或是新增加上的,如许就辨别了“旧”数据和“新”数据,那下一步就是把“旧”的删除,把“新”的纪录了。
我们再到索引器看看,由于我们对TempData的操纵是从索引器入手下手的,上面是索引器的代码:
publicobjectthis[stringkey]{
get{
objectvalue;
if(TryGetValue(key,outvalue)){
returnvalue;
}
returnnull;
}
set{
_data[key]=value;
_modifiedKeys.Add(key);
}
}
当我们TempData["msg"]=newObject();时不但向_data中增加了数据,同时_modifiedKeys也保留了“新”数据的key。那甚么时分“新”数据被保留“旧”数据被删除,真实的实行呢?这个历程是在Load和Save办法中产生的。上面看它们的详细完成:
publicvoidLoad(ControllerContextcontrollerContext,ITempDataProvidertempDataProvider){
IDictionary<string,object>providerDictionary=tempDataProvider.LoadTempData(
controllerContext);
_data=(providerDictionary!=null)?newDictionary<string,object>(providerDictionary,
StringComparer.OrdinalIgnoreCase):newDictionary<string,object>
(StringComparer.OrdinalIgnoreCase);
_initialKeys=newHashSet<string>(_data.Keys);
_modifiedKeys.Clear();
}
publicvoidSave(ControllerContextcontrollerContext,ITempDataProvidertempDataProvider){
if(_modifiedKeys.Count>0){
//Applychangetracking.
foreach(stringxin_initialKeys){
if(!_modifiedKeys.Contains(x)){
_data.Remove(x);
}
}
//Storethedictionary
tempDataProvider.SaveTempData(controllerContext,_data);
}
}
我们看到TempDataDictionary的Load办法起首是挪用了ITempDataProvider的LoadTempData办法来猎取tempdata容器,然后让_initialKeys即是_data.Keys,相称于保留了“旧”数据的key,然后清空_modifiedKeys,相称于今朝没有“新”数据。而Save办法则是反省_modifiedKeys.Count是不是年夜于0,就相称于反省是不是有“新”数据,有则挪用ITempDataProveder的SaveTempData办法保留失落“新”数据。这里也考证了我们先前的料想是准确的。
说到这里,我们仿佛还没有发明没有一个中央挪用TempDataDictionary的Load和Save办法,也就是说“新”“旧”数据一向在都在_data中,仿佛“旧”的数据没有真正删除,“新”数据也一向没有一个安宁的家。
我们说对TempData中数据的“革新”操纵(革新操纵即把“旧”数据删除,把“新”数据保留)应当产生在实行Action的时分,那在甚么中央我们实行了Action呢,是在IController的Execute办法中,IController<=ControllerBase<=Controller,顺着如许的承继按次,我们找到Controller类的ExecuteCore办法,这里是实行Action的中央,上面我们看看ExecuteCore办法的完成:
protectedoverridevoidExecuteCore(){
TempData.Load(ControllerContext,TempDataProvider);
try{
stringactionName=RouteData.GetRequiredString("action");
if(!ActionInvoker.InvokeAction(ControllerContext,actionName)){
HandleUnknownAction(actionName);
}
}
finally{
TempData.Save(ControllerContext,TempDataProvider);
}
}
我们看到在这里,Action实行之前TempData.Load,Action实行以后TempData.Save。这就完成了TempData的“革新”操纵。
SessionStateTempDataProvider与ITempDataProviderTop
到这里,我们发明仿佛还不晓得究竟数据是怎样被保留的,我们只晓得ITempDataProvider供应了一个保留数据和猎取容器的这么一个商定,那末详细的完成一定是承继了ITempDataProvider接口的类来做,SessionStateTempDataProvider就是这么一个类。
我们晓得是在Controller类中的ExecuteCore办法中实行了“革新”操纵,我们还晓得TempDataDictionary的Load和Save办法必要一个ITempDataProvider的办法,那末我们能够揣度一定要往Controller类中寻觅ITempDataProvider的完成。如我们所料:
publicITempDataProviderTempDataProvider{
get{
if(_tempDataProvider==null){
_tempDataProvider=newSessionStateTempDataProvider();
}
return_tempDataProvider;
}
set{
_tempDataProvider=value;
}
}
这里利用了属性注进,倔强的注进了一个SessionStateTempDataProvider工具。那末详细是如何完成存储的就要往看一下SessionStateTempDataProvider类了。
SessionStateTempDataProvider有一个常字符串字段:
internalconststringTempDataSessionStateKey="__ControllerTempData";
上面是LoadTempData办法:
publicvirtualIDictionaryLoadTempData(ControllerContextcontrollerContext){
HttpContextBasehttpContext=controllerContext.HttpContext;
if(httpContext.Session==null){
thrownewInvalidOperationException(MVCResources.SessionStateTempDataProvider_SessionStateDisabled);
}
Dictionary<string,object>tempDataDictionary=httpContext.Session[TempDataSessionStateKey]asDictionary<string,object>;
if(tempDataDictionary!=null){
//IfwegotitfromSession,removeitsothatnootherrequestgetsit
httpContext.Session.Remove(TempDataSessionStateKey);
returntempDataDictionary;
}
else{
returnnewDictionary<string,object>(StringComparer.OrdinalIgnoreCase);
}
}
下面的代码很复杂,本来它把Dictionary范例的数据存进了Session["__ControllerTempData"]里,读的时分也只是复杂的范例转换一下就前往了。
上面是SaveTempData办法:
publicvirtualvoidSaveTempData(ControllerContextcontrollerContext,IDictionaryvalues){
HttpContextBasehttpContext=controllerContext.HttpContext;
if(httpContext.Session==null){
thrownewInvalidOperationException(
MVCResources.SessionStateTempDataProvider_SessionStateDisabled);
}
httpContext.Session[TempDataSessionStateKey]=values;
}
SaveTempData办法也很复杂。
总结Top
ITempDataProvider只是一个供应一时数据存取的一个商定的接口,它其实不供应怎样办理“新旧”数据,TempDataDictionary类才是真正办理“新旧”数据的办理者,可是这个“办理者”必要一个存取“新旧”数据的路子,也就是说它告知ITempDataProvider该存甚么该取甚么,然后由ITempDataProvider真实的往实行存取操纵。在Controller实行Action之前,这个“办理者”要获得上一次的“旧”数据,Action停止以后它还要把“新”数据给存起来。而Controller好似这么一个“批示者”,它把一个能做ITempDataProvider事变的类——SessionStateTempDataProvider交给TempDataProvider利用。上面用一个类图归纳综合一下几个类的干系。

对于new隐藏成员的作用,往往是出于使用了一个第三方类库,而你又无法获得这个类库的源代码,当你继承这个类库的某个类时,你需要重新实现其中的一个方法,而又需要与父类中的函数使用同样的函数,这是就需要在自定义的子类中把那个同名函数(或成员)加上new标记,从而隐藏父类中同名的成员。
灵魂腐蚀 该用户已被删除
9#
发表于 2015-3-23 07:11:35 | 只看该作者
由于JSP/Servlet都是基于Java的,所以它们也有Java语言的最大优点——平台无关性,也就是所谓的“一次编写,随处运行(WORA–WriteOnce,RunAnywhere)”。除了这个优点,JSP/Servlet的效率以及安全性也是相当惊人的。
简单生活 该用户已被删除
8#
发表于 2015-3-16 22:11:35 | 只看该作者
当然我们在选择Asp.net主机是,除了要考虑服务提供商在版本是否是实时更新以外,机房的环境和配置也是非常重要的,通常选择骨干网的机房,在速度和稳定性上会非常有保证。
冷月葬花魂 该用户已被删除
7#
发表于 2015-3-9 10:22:35 | 只看该作者
以上是语言本身的弱点,在功能方面ASP同样存在问题,第一是功能太弱,一些底层操作只能通过组件来完成,在这点上是远远比不上PHP/JSP,其次就是缺乏完善的纠错/调试功能,这点上ASP/PHP/JSP差不多。
活着的死人 该用户已被删除
6#
发表于 2015-2-27 15:43:15 | 只看该作者
对于中小项目来说.net技术是完全可以胜任,但为什么现在大型公司或网站都选择php或java呢?就是因为微软不够开放,没有提供从硬件到应用服务器再到业务应用的整套解决方案。
山那边是海 该用户已被删除
5#
发表于 2015-2-9 18:18:45 | 只看该作者
大哥拜托,Java在95年就出来了,微软垄断个妹啊,服务器市场微软完全是后后来者,当年都是Unix的市场,现在被WindowsServer和Linux抢下大片,包括数据库也一样。
小女巫 该用户已被删除
地板
发表于 2015-2-4 06:57:08 | 只看该作者
弱类型造成潜在的出错可能:尽管弱数据类型的编程语言使用起来回方便一些,但相对于它所造成的出错几率是远远得不偿失的。
爱飞 该用户已被删除
板凳
发表于 2015-1-25 21:29:24 | 只看该作者
众所周知,Windows以易用而出名,也因此占据不少的服务器市场。
因胸联盟 该用户已被删除
沙发
发表于 2015-1-18 14:38:14 | 只看该作者
ASP.NET可以无缝地与WYSIWYGHTML编辑器和其他编程工具(包括MicrosoftVisualStudio.NET)一起工作。这不仅使得Web开发更加方便,而且还能提供这些工具必须提供的所有优点,包括开发人员可以用来将服务器控件拖放到Web页的GUI和完全集成的调试支持。微软为ASP.net设计了这样一些策略:易于写出结构清晰的代码、代码易于重用和共享、可用编译类语言编写等等,目的是让程序员更容易开发出Web应用,满足计算向Web转移的战略需要。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-9-24 11:34

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表