仓酷云

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

[学习教程] ASP.NET网页编程之基于Json.NET本人完成MVC中的JsonValueProviderFactory仓酷云

[复制链接]
逍遥一派 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:14:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
有时也搞不懂应该学那种;主要看你以后去的那个公司是使用哪种了。就像王千祥的课上说的:企业应用现在主要就三层(其实也差不多就是MVC):表示层(主要使用html写的,很简单)、业务逻辑层(主要就是应用服务器的)。最后就是数据层(其实就是学习数据库)写了博文ASP.NETMVC3晋级至MVC5.1的遭受:“已增加了具有不异键的项”以后,持续看着System.Web.Mvc.JsonValueProviderFactory的开源代码。
越看越不扎眼,越看内心越不爽!不爽的中央次要有两个:
1)仍然在利用用功能低下且不开源的JavaScriptSerializer!打逝世也不必Json.NET!
2)作为一个工场类,JsonValueProviderFactory完成庞大,并且工场临盆出的产物DictionaryValueProvider(IValueProvider的一个完成)也很庞大。
【先看第一个不爽】
JsonValueProviderFactory的事情之一是对json字符串举行反序列化,而Json.NET的反序列化功能远超JavaScriptSerializer,请看下图:

而微软MVC开辟职员仍然不思朝上进步,用自家工具的痴心不改,持续用着JavaScriptSerializer。
  1. privatestaticobjectGetDeserializedObject(ControllerContextcontrollerContext){//...JavaScriptSerializerserializer=newJavaScriptSerializer();objectjsonData=serializer.DeserializeObject(bodyText);returnjsonData;}
复制代码

仅凭这一点,就让我发生了如许的感动——基于Json.NET本人完成一个JsonValueProviderFactory。
【再看第二个不爽】
作为一个工场类,JsonValueProviderFactory承继自ValueProviderFactory,重载了ValueProviderFactory的笼统办法GetValueProvider,前往接口IValueProvider的一个完成。(ControllerActionInvoker就是经由过程IValueProvider接口依据key失掉Action各个参数的值)
IValueProvider的代码以下:
  1. namespaceSystem.Web.Mvc{publicinterfaceIValueProvider{boolContainsPrefix(stringprefix);ValueProviderResultGetValue(stringkey);}}
复制代码

接口很复杂,先反省prefix是不是存在,假如存在经由过程key取值。
JsonValueProviderFactory前往的DictionaryValueProvider就是干这个活的,可是为了临盆DictionaryValueProvider,JsonValueProviderFactory举行了庞大的搬箱子操纵,不但用到了递回,并且还用了多个IDictionary<string,object>,代码让人看得头晕。
再看看DictionaryValueProvider的完成,也是庞大,并且还用到了PrefixContainer。
复杂算个账:JsonValueProviderFactory的代码用了120行,DictionaryValueProvider的代码用了63行,PrefixContainer的代码用了219,一共用了402行代码(包括空行与定名空间的援用)。有些奢靡!
必要这么庞大吗?有更复杂的办理办法吗?
【感动不如举动】
办理成绩的关头在于怎样以更复杂的办法完成IValueProvider的两个操纵——ContainsPrefix与GetValue。
要完成这两个操纵,先要摸清prefix与key的纪律。因而先完成一个MockValueProvider,经由过程日记纪录ControllerActionInvoker挪用这个接口时利用的参数。
经由过程日记信息,找出了如许的纪律:
1.假如Action的参数是如许的:
  1. publicActionResultPostList(AggSiteModelmodel){}
复制代码
ControllerActionInvoker会如许挪用:
ContainsPrefix("model")->假如前往False->以AggSiteModel的属性称号顺次ContainsPrefix,好比ContainsPrefix("PageTitle")【注:PageTitle是AggSiteModel的一个属性】->假如前往True->会以prefix为key挪用GetValue。
2.假如Action的参数是数组:
  1. publicActionResultPostList(AggSiteModel[]model){}
复制代码
ControllerActionInvoker会如许挪用:
ContainsPrefix("[0]")->假如前往True->ContainsPrefix("[0].PageTitle")->假如前往True->GetValue("[0].PageTitle")
3.仍然是第1种的Action参数情势,只不外AggSiteModel有聚合。
  1. publicclassAggSiteModel{publicstringPageTitle{get;set;}publicPagingBuilderPaging{get;set;}}
复制代码
ControllerActionInvoker会如许挪用:
ContainsPrefix("model")->假如前往False->ContainsPrefix("Paging.PageTitle")
看到这些key的特性,想到了Json.NET中的SelectTokens:
  1. ///<summary>///SelectsacollectionofelementsusingaJPathexpression.///</summary>///<paramname="path">///A<seecref="String"/>thatcontainsaJPathexpression.///</param>///<returns>An<seecref="IEnumerable{JToken}"/>thatcontainstheselectedelements.</returns>publicIEnumerable<JToken>SelectTokens(stringpath){returnSelectTokens(path,false);}
复制代码

这是里key居然与JPath惊人的类似!
看来Json.NET不但能够弄定JsonValueProviderFactory,还能够弄定DictionaryValueProvider+PrefixContainer,完成代码应当不会凌驾100行。
【基于Json.NET完成CnblogsJsonValueProviderFactory】
  1. publicclassCnblogsJsonValueProviderFactory:ValueProviderFactory{publicoverrideIValueProviderGetValueProvider(ControllerContextcontrollerContext){if(controllerContext==null)thrownewArgumentNullException("controllerContext");if(!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json",StringComparison.OrdinalIgnoreCase)){returnnull;}varbodyText=string.Empty;using(varreader=newStreamReader(controllerContext.HttpContext.Request.InputStream)){bodyText=reader.ReadToEnd();}if(string.IsNullOrEmpty(bodyText))returnnull;returnnewJObjectValueProvider(bodyText.StartsWith("[")?JArray.Parse(bodyText)asJContainer:JObject.Parse(bodyText)asJContainer);}}publicclassJObjectValueProvider:IValueProvider{privateJContainer_jcontainer;publicJObjectValueProvider(JContainerjcontainer){_jcontainer=jcontainer;}publicboolContainsPrefix(stringprefix){return_jcontainer.SelectToken(prefix)!=null;}publicValueProviderResultGetValue(stringkey){varjtoken=_jcontainer.SelectToken(key);if(jtoken==null||jtoken.Type==JTokenType.Object)returnnull;returnnewValueProviderResult(jtoken.ToObject<object>(),jtoken.ToString(),CultureInfo.CurrentCulture);}}
复制代码

包括空行与定名空间的援用,一共只要61行代码,远远少于MVC中的402行代码。
在项目中利用这个CnblogsJsonValueProviderFactory:
  1. protectedvoidApplication_Start(Objectsender,EventArgse){ValueProviderFactories.Factories.Remove(ValueProviderFactories.Factories.OfType<JsonValueProviderFactory>().FirstOrDefault());ValueProviderFactories.Factories.Add(newCnblogsJsonValueProviderFactory());}
复制代码

【十全十美】
Json.NET中的SelectTokens的path参数辨别巨细写,利用CnblogsJsonValueProviderFactory,在js中写json时,巨细写必需要婚配。
看了一下Json.NET的开源代码,发明是与上面的代码有关:
  1. internalclassJPropertyKeyedCollection:Collection<JToken>{privatestaticreadonlyIEqualityComparer<string>Comparer=StringComparer.Ordinal;}
复制代码
假如把StringComparer.Ordinal改成StringComparer.OrdinalIgnoreCase就可以办理成绩,可是不晓得会不会给Json.NET的功能带来影响。
严厉辨别巨细写也能承受,可让代码更标准一些。
听03很多师兄说主讲老师杭城方讲课很差就连旁听也没有去了)
小女巫 该用户已被删除
沙发
发表于 2015-1-19 13:08:31 | 只看该作者
如今主流的Web服务器软件主要由IIS或Apache组成。IIS支持ASP且只能运行在Windows平台下,Apache支持PHP,CGI,JSP且可运行于多种平台,虽然Apache是世界使用排名第一的Web服务器平台。
变相怪杰 该用户已被删除
板凳
发表于 2015-1-24 12:42:05 | 只看该作者
由于JSP/Servlet都是基于Java的,所以它们也有Java语言的最大优点——平台无关性,也就是所谓的“一次编写,随处运行(WORA–WriteOnce,RunAnywhere)”。除了这个优点,JSP/Servlet的效率以及安全性也是相当惊人的。
深爱那片海 该用户已被删除
地板
发表于 2015-1-25 14:49:43 | 只看该作者
它可通过内置的组件实现更强大的功能,如使用A-DO可以轻松地访问数据库。
莫相离 该用户已被删除
5#
发表于 2015-1-27 17:52:39 | 只看该作者
那么,ASP.Net有哪些改进呢?
若天明 该用户已被删除
6#
发表于 2015-2-5 08:23:46 | 只看该作者
逐步缩小出错代码段的范围,最终确定错误代码的位置。
飘飘悠悠 该用户已被删除
7#
发表于 2015-2-11 08:03:40 | 只看该作者
但是java靠开源打出的一片天地,特别是在微软的垄断下能打开今天的局面还是有它的生命力的。
飘灵儿 该用户已被删除
8#
发表于 2015-3-1 23:49:35 | 只看该作者
使用普通的文本编辑器编写,如记事本就可以完成。由脚本在服务器上而不是客户端运行,ASP所使用的脚本语言都在服务端上运行,用户端的浏览器不需要提供任何别的支持,这样大提高了用户与服务器之间的交互的速度。
透明 该用户已被删除
9#
发表于 2015-3-5 19:10:26 | 只看该作者
可以通过在现有ASP应用程序中逐渐添加ASP.NET功能,随时增强ASP应用程序的功能。ASP.NET是一个已编译的、基于.NET的环境,可以用任何与.NET兼容的语言(包括VisualBasic.NET、C#和JScript.NET.)创作应用程序。另外,任何ASP.NET应用程序都可以使用整个.NETFramework。开发人员可以方便地获得这些技术的优点,其中包括托管的公共语言运行库环境、类型安全、继承等等。
简单生活 该用户已被删除
10#
发表于 2015-3-12 11:25:52 | 只看该作者
网页从开始简单的hmtl到复杂的服务语言,走过了10多个年头,各种技术层出不穷,单个的主流技术也在不断翻新的版本,现在分析下各种语言的区别、优势、劣势、开发注意事项!
海妖 该用户已被删除
11#
发表于 2015-3-13 11:08:32 | 只看该作者
平台无关性是PHP的最大优点,但是在优点的背后,还是有一些小小的缺点的。如果在PHP中不使用ODBC,而用其自带的数据库函数(这样的效率要比使用ODBC高)来连接数据库的话,使用不同的数据库,PHP的函数名不能统一。这样,使得程序的移植变得有些麻烦。不过,作为目前应用最为广泛的一种后台语言,PHP的优点还是异常明显的。
分手快乐 该用户已被删除
12#
发表于 2015-3-19 21:27:40 | 只看该作者
CGI程序在运行的时候,首先是客户向服务器上的CGI程序发送一个请求,服务器接收到客户的请求后,就会打开一个新的Process(进程)来执行CGI程序,处理客户的请求。CGI程序最后将执行的结果(HTML页面代码)传回给客户。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-12-24 01:02

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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