JSON.NET 加载json字符串时,如何自定义映射到某个属性?

问题描述

JSON.NET加载json字符串时,如何自定义映射到某个属性?例如,原来写JSON时属性叫“Name",现在叫”NewName“,如何把旧的名称,映射到新的属性上?有没有类似IXmlSerializable的接口,可以自定义读写过程?

解决方案

解决方案二:
staticclassProgram{classMy{[JsonProperty("Name")]//用JsonProperty特性publicstringNewName{get;set;}}staticvoidMain(){stringjson="{'Name':'JamesBond'}";Mymy=JsonConvert.DeserializeObject<My>(json);//my.NewName:"JamesBond"}}

解决方案三:
引用1楼Forty2的回复:

staticclassProgram{classMy{[JsonProperty("Name")]//用JsonProperty特性publicstringNewName{get;set;}}staticvoidMain(){stringjson="{'Name':'JamesBond'}";Mymy=JsonConvert.DeserializeObject<My>(json);//my.NewName:"JamesBond"}}

这样确实是可以解决掉读取旧名称问题,问题是,再写JSON时,还是要用“Name”写,而不是“NewName”啊?我的本意是要解决数据文件的升级,同时兼容旧文件(属性名称)。
解决方案四:
json.net可以通过attribute来实现
解决方案五:
classMy{[JsonProperty(PropertyName="Name",DefaultValueHandling=DefaultValueHandling.Ignore)]privatestring_name_for_old_contract{get{returnnull;}set{NewName=value;}}[JsonProperty]publicstringNewName{get;set;}}

解决方案六:
新旧名字问题没办法,读出来后你可以通过automapper再映射到最新的实体
解决方案七:
直接映射不行,你要先重新定义一个json结构体,然后把新旧JSON合并
解决方案八:
引用4楼Forty2的回复:

classMy{[JsonProperty(PropertyName="Name",DefaultValueHandling=DefaultValueHandling.Ignore)]privatestring_name_for_old_contract{get{returnnull;}set{NewName=value;}}[JsonProperty]publicstringNewName{get;set;}}

引用6楼lshfong的回复:

直接映射不行,你要先重新定义一个json结构体,然后把新旧JSON合并

多谢2位,谢谢你们的思路。不过,感觉这样有一个弊端,就是如果每次改1-2个属性,必须保留整个的旧实体类在代码中。有没有办法,可以反序列化时,由代码介入,同时,可分级处理,例如:classA{intIDClassBBDeserialize(){//A类反序列化自己的部分,B类部分,交由B类反序列化B.Deserialize(ContextObjectcontext)}}classClassB{Deserialize(){//B类反序列化自己}}
解决方案九:
兼容性是永远存在的问题,不论你用什么方式来“处理”,总之都抹不掉痕迹。但是你可以用“倒置”的方式来重构你的系统。例如原来有一个class包厢{publicstring门牌号;publicint价格;...................}

后来改为public包厢{publicstring包厢号;publicint价格;..............}

假设此时不允许暴露“门牌号”字段,那么你需要为以前的数据单独设计一个兼容类型,例如internal包厢V1版:包厢{publicstring门牌号{get{returnthis.包厢号;}set{this.包厢号=value;}}}

并且在可以确定是新数据上使用“包厢”,在不确定只有新数据时使用“包厢V1版”。等将来再删除包厢V1版,或者永远也不删除。但是新系统,对外已经不提供包厢V1版的类型定义了。
解决方案十:
引用7楼oldhunter的回复:

不过,感觉这样有一个弊端,就是如果每次改1-2个属性,必须保留整个的旧实体类在代码中。

那说明你没有什么抽象层设计,都是把原本最底层的东西放到最顶层接口来编写代码。
解决方案十一:
引用8楼sp1234的回复:

兼容性是永远存在的问题,不论你用什么方式来“处理”,总之都抹不掉痕迹。但是你可以用“倒置”的方式来重构你的系统。例如原来有一个class包厢{publicstring门牌号;publicint价格;...................}

后来改为public包厢{publicstring包厢号;publicint价格;..............}

假设此时不允许暴露“门牌号”字段,那么你需要为以前的数据单独设计一个兼容类型,例如internal包厢V1版:包厢{publicstring门牌号{get{returnthis.包厢号;}set{this.包厢号=value;}}}

并且在可以确定是新数据上使用“包厢”,在不确定只有新数据时使用“包厢V1版”。等将来再删除包厢V1版,或者永远也不删除。但是新系统,对外已经不提供包厢V1版的类型定义了。

多谢多谢!思路很完美!延伸2个技术层面的问题:1、解析JSON字符串时,如何判断数据版本号?要写一个属性吗?还是JSON.NET有现成的Atrribute?2、如果包含的”引用类型“升级后,如何把解析分配给”旧版本“的引用类型?如下所示:序列化JSON是以“火车”为单位处理的,而“火车”又包含了“包厢”,”包厢“类升级后,如何将数据解析到”包厢V1版“?用JSON.NET如何处理?因为JSON.NET正常是解析到”包厢“类。(JSON.NET即:Newtonsoft.Json)class火车{publicstring名称;public包厢所属包厢;}class包厢{publicstring门牌号;publicint价格;...................}internal包厢V1版:包厢{publicstring门牌号{get{returnthis.包厢号;}set{this.包厢号=value;}}}

解决方案十二:
感觉你们讨论是没有意义的楼主最初的问题应该是兼容不同来源json但你们的讨论中,是以已知差异的具象为前提的:差异不同,代码也不同而事实是:你根本就不会知道你明天会有什么新想法也就是你不可能预知未来的差异会在哪里和是什么如果出现差异就修改程序,显然就离开了问题的初衷
解决方案十三:
引用11楼xuzuning的回复:

感觉你们讨论是没有意义的楼主最初的问题应该是兼容不同来源json但你们的讨论中,是以已知差异的具象为前提的:差异不同,代码也不同而事实是:你根本就不会知道你明天会有什么新想法也就是你不可能预知未来的差异会在哪里和是什么如果出现差异就修改程序,显然就离开了问题的初衷

可以基于一些范围假设:1、未来数据基于JSON2、属性名称重构后,可兼容旧属性,同时满足代码的可维护性、封装性(个人觉得,用“从新版本继承一个实体类,解析旧属性”的解决方案就不错,即sp1234的思路)3、增加新属性:只能使用默认值,或基于旧属性转换(从新版本继承一个实体类,解析旧属性)4、引用子类的类名、属性重构(需要讨论:如何让json在解析时,自定义解析流程,即根据版本号解析到不同的类。其实主类好办,引用子类如何选择?JSON.NET类库是否提供了这方面的扩展,如Newtonsoft.Json.Serialization.DefaultContractResolver)5、类引用关联重构、业务逻辑重构:这个范围就太大了,不好控制,有可能基于“旧类”解析已经没有意义,无法兼容。
解决方案十四:
如何让json在解析时,自定义解析流程,即根据版本号解析到不同的类。其实主类好办,引用子类如何选择?JSON.NET类库是否提供了这方面的扩展,如Newtonsoft.Json.Serialization.DefaultContractResolver
解决方案十五:
我觉得你有空讨论这个,还不如自己实现一个json,又不是很复杂的工作

时间: 2024-09-16 19:47:48

JSON.NET 加载json字符串时,如何自定义映射到某个属性?的相关文章

Google官方网络框架-Volley的使用解析Json以及加载网络图片方法

Google官方网络框架-Volley的使用解析Json以及加载网络图片方法 Volley是什么? Google I/O 大会上,Google 推出 Volley的一个网络框架 Volley适合什么场景? Volley适合网络通信频繁操作,并能同时实现多个网络通信. 下载地址:http://download.csdn.net/detail/qq_26787115/9358787 1.Volley的使用解析Json 我们不罗嗦,直接开讲: 我们的需求很简单,就是做一个归属地查询的小软件,使用Vol

解决Ajax加载JSon数据中文乱码问题

一.问题描述 使用zTree的异步刷新父级菜单时,服务器返回中文乱码,但项目中使用了SpringMvc,已经对中文乱码处理,为什么还会出现呢? 此处为的异步请求的配置: Java代码 async: { enable: true, url: basePath + '/sysMenu/listSysMenu', autoParam: ["id=parentId"] } SpringMvc中文字符处理: Java代码 <mvc:annotation-driven> <mvc

图片-WebGL加载json模型,贴图混论处理

问题描述 WebGL加载json模型,贴图混论处理 使用3dmax建立模型,后导出为OBJ+mtl,然后转JSON,但加载时出现比较多的贴图混乱,比如 情况一: 情况二: 不知从何下手~~有没有批量修改调整的办法呢? 解决方案 最后是用了Three.js中,设置 material.map.wrapS = true material.map.wrapS = true 将贴图的repeat信息进行手动设置,就可以叻 谢谢热心人解答 解决方案二: http://www.html5china.com/H

Easyui 菜单树实例 PHP+MySQL后台加载json

实例一 PHP+MySQL+Easyui tree菜单从后台加载json数据 实现功能:从数据库加载出所有的数据库名,相应的数据库加载对应的数据库表名 异步加载Tree tree 支持内置的异步加载模式,用户创建一个空的tree,然后定义一个远程服务器站点返回json数据用于填充tree来异步满足异步加载需求 <ul id="tree"></ul> 使用javascript加载数据 <script> $('#tree').tree( {     ur

json写的jsp加载json写的js页面为什么有时候会不兼容?

问题描述 json写的jsp加载json写的js页面为什么有时候会不兼容? json写的jsp加载json写的js页面为什么有时候会不兼容? 解决方案 不知道你说的不兼容是什么意思,是不兼容开发环境还是不兼容浏览器?建议你用框架,它们已经考虑了兼容适配的问题.

求助,在线等,java+ssm项目初始化数据问题解析json文件加载到数据库,跪谢!

问题描述 求助,在线等,java+ssm项目初始化数据问题解析json文件加载到数据库,跪谢! 服务器能不能在启动的时候加载json文件 然后把数据 加载到数据库!就是启动服务器,然后启动成功后,数据库要看到有基本数据的效果,可以实现吗?在线等!跪谢!

url-在JS里如何通过URL加载json数据

问题描述 在JS里如何通过URL加载json数据 我有一个函数L.mapbox.map('map','URL'),其中这个URL要怎么链接到本地的数据呢?路径应该是怎样的? 解决方案 js获取Url后的数据转换为json 解决方案二: 安全问题加载不了本地数据,url写 你服务器网站的url地址,而且不能跨域

jsonp-怎样使easyui的json重新加载

问题描述 怎样使easyui的json重新加载 List selectPProduct = productClassFacade.selectPProductClassListLazy(map); setOperate(selectPProduct, request.getContextPath()); String json = JSONArray.fromObject(selectPProduct).toString(); System.out.println(json+"!!!!!!!!!

tree-ext树加载JSON显示不出子节点

问题描述 ext树加载JSON显示不出子节点 使用ext加载树结构时候接受的JSON串如下, [{ "id": "10211", "text": "中心", "leve": 1, "children": [{ "id": "13f7b495-9967-1031-9a46-b63f19c07715", "text": "