ASP.NET网页编程之基于Json.NET本人完成MVC中的JsonValueProviderFactory仓酷云
有时也搞不懂应该学那种;主要看你以后去的那个公司是使用哪种了。就像王千祥的课上说的:企业应用现在主要就三层(其实也差不多就是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。
privatestaticobjectGetDeserializedObject(ControllerContextcontrollerContext){//...JavaScriptSerializerserializer=newJavaScriptSerializer();objectjsonData=serializer.DeserializeObject(bodyText);returnjsonData;}
仅凭这一点,就让我发生了如许的感动——基于Json.NET本人完成一个JsonValueProviderFactory。
【再看第二个不爽】
作为一个工场类,JsonValueProviderFactory承继自ValueProviderFactory,重载了ValueProviderFactory的笼统办法GetValueProvider,前往接口IValueProvider的一个完成。(ControllerActionInvoker就是经由过程IValueProvider接口依据key失掉Action各个参数的值)
IValueProvider的代码以下:
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的参数是如许的:
publicActionResultPostList(AggSiteModelmodel){}ControllerActionInvoker会如许挪用:
ContainsPrefix("model")->假如前往False->以AggSiteModel的属性称号顺次ContainsPrefix,好比ContainsPrefix("PageTitle")【注:PageTitle是AggSiteModel的一个属性】->假如前往True->会以prefix为key挪用GetValue。
2.假如Action的参数是数组:
publicActionResultPostList(AggSiteModel[]model){}ControllerActionInvoker会如许挪用:
ContainsPrefix("")->假如前往True->ContainsPrefix(".PageTitle")->假如前往True->GetValue(".PageTitle")
3.仍然是第1种的Action参数情势,只不外AggSiteModel有聚合。
publicclassAggSiteModel{publicstringPageTitle{get;set;}publicPagingBuilderPaging{get;set;}}ControllerActionInvoker会如许挪用:
ContainsPrefix("model")->假如前往False->ContainsPrefix("Paging.PageTitle")
看到这些key的特性,想到了Json.NET中的SelectTokens:
///<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】
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:
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的开源代码,发明是与上面的代码有关:
internalclassJPropertyKeyedCollection:Collection<JToken>{privatestaticreadonlyIEqualityComparer<string>Comparer=StringComparer.Ordinal;}假如把StringComparer.Ordinal改成StringComparer.OrdinalIgnoreCase就可以办理成绩,可是不晓得会不会给Json.NET的功能带来影响。
严厉辨别巨细写也能承受,可让代码更标准一些。
听03很多师兄说主讲老师杭城方讲课很差就连旁听也没有去了) 如今主流的Web服务器软件主要由IIS或Apache组成。IIS支持ASP且只能运行在Windows平台下,Apache支持PHP,CGI,JSP且可运行于多种平台,虽然Apache是世界使用排名第一的Web服务器平台。 由于JSP/Servlet都是基于Java的,所以它们也有Java语言的最大优点——平台无关性,也就是所谓的“一次编写,随处运行(WORA–WriteOnce,RunAnywhere)”。除了这个优点,JSP/Servlet的效率以及安全性也是相当惊人的。 它可通过内置的组件实现更强大的功能,如使用A-DO可以轻松地访问数据库。 那么,ASP.Net有哪些改进呢? 逐步缩小出错代码段的范围,最终确定错误代码的位置。 但是java靠开源打出的一片天地,特别是在微软的垄断下能打开今天的局面还是有它的生命力的。 使用普通的文本编辑器编写,如记事本就可以完成。由脚本在服务器上而不是客户端运行,ASP所使用的脚本语言都在服务端上运行,用户端的浏览器不需要提供任何别的支持,这样大提高了用户与服务器之间的交互的速度。 可以通过在现有ASP应用程序中逐渐添加ASP.NET功能,随时增强ASP应用程序的功能。ASP.NET是一个已编译的、基于.NET的环境,可以用任何与.NET兼容的语言(包括VisualBasic.NET、C#和JScript.NET.)创作应用程序。另外,任何ASP.NET应用程序都可以使用整个.NETFramework。开发人员可以方便地获得这些技术的优点,其中包括托管的公共语言运行库环境、类型安全、继承等等。 网页从开始简单的hmtl到复杂的服务语言,走过了10多个年头,各种技术层出不穷,单个的主流技术也在不断翻新的版本,现在分析下各种语言的区别、优势、劣势、开发注意事项! 平台无关性是PHP的最大优点,但是在优点的背后,还是有一些小小的缺点的。如果在PHP中不使用ODBC,而用其自带的数据库函数(这样的效率要比使用ODBC高)来连接数据库的话,使用不同的数据库,PHP的函数名不能统一。这样,使得程序的移植变得有些麻烦。不过,作为目前应用最为广泛的一种后台语言,PHP的优点还是异常明显的。 CGI程序在运行的时候,首先是客户向服务器上的CGI程序发送一个请求,服务器接收到客户的请求后,就会打开一个新的Process(进程)来执行CGI程序,处理客户的请求。CGI程序最后将执行的结果(HTML页面代码)传回给客户。
页:
[1]