再谈Newtonsoft.Json高级用法
上一篇Newtonsoft.Json高级用法发布以后收到挺多回复的,本篇将分享几点挺有用的知识点和最近项目中用到的一个新点进行说明,做为对上篇文章的补充。
阅读目录
动态改变属性序列化名称
"动态改变属性序列化名称"顾名思义:在不同场景下实体字段序列化后字段名称不同,比如有下面实体A,正常序列化后json为{"Id":"123"}
public class A
{
public string Id { get; set; }
}
现在有两种新场景A场景下 字段Id需要序列化为Key,B场景下字段Id需要序列化为id,那么如何在不改变实体代码情形下完成该功能呢?下面以树形结构数据为例子进行讲解。
各种各样的前端树形控件所要求数据格式不一样,下面列举几种常见的树形控件数据格式。
//bootstrap treeview,数据结构为
[
{
id:'1', //节点id
text: '父节点', //节点显示文本
icon: 'glyphicon glyphicon-cloud-download', //节点图标样式
nodes:[{id:'2',text:'子节点'}] //子节点
}
] //zTree
[
{ "id" : "1", "name" : "父节点1", "children" : [{id:'4',name:'子节点1'}] },
{ "id" : "2", "name" : "父节点2", "children" : [{id:'5',name:'子节点2'}] },
{ "id" : "3", "name" : "父节点3", "children" : [{id:'6',name:'子节点3'}] }
]
两者之间字段对比
| treeview | zTree | |
| 节点id | id | id |
| 显示文本 | text | name |
| 图标 | icon | icon |
| 子节点 | nodes | children |
标红部分是数据格式区别,假设后台定义的树形实体如下
/// <summary>
/// 树形实体
/// </summary>
public class Tree
{
/// <summary>
/// 当前ID
/// </summary>
public string Id { get; set; } /// <summary>
/// 文本
/// </summary>
public string Text { get; set; } /// <summary>
/// 附加信息
/// </summary>
public string Tag { get; set; } /// <summary>
/// 节点图标
/// </summary>
public string Icon { get; set; } /// <summary>
/// 子级
/// </summary>
public List<Tree> Childrens { get; set; }
}
/// <summary>
/// 树形实体
/// </summary>
public class Tree
{
/// <summary>
/// 当前ID
/// </summary>
public string id { get; set; } /// <summary>
/// 文本
/// </summary>
public string text { get; set; } /// <summary>
/// 附加信息
/// </summary>
public string Tag { get; set; } /// <summary>
/// 节点图标
/// </summary>
public string Icon { get; set; } /// <summary>
/// 子级
/// </summary>
public List<Tree> nodes { get; set; }
}
其中标红部分是修改的,当然还需要修改对Tree实体赋值的代码,这里就不列出了。
方法二 前台js处理
var data=[
{"Id":"1","Text":"父节点1","Childrens":[
{"Id":"3","Text":"子节点1","Childrens":[{"Id":"5","Text":"子节点1-1"}]},
{"Id":"4","Text":"子节点2"}
]},
{"Id":"2","Text":"父节点2","Childrens":[
{"Id":"5","Text":"子节点3"}
]}]
//将后台返回数据转换成treeview所需格式数据
handleChild(data);
console.log(data); //转换后台实体数据为treeview符合的数据格式
function handleChild(childs){
for(var i=0,length=childs.length;i<length;i++){
var item=childs[i];
item.id=item.Id;
item.text=item.Text;
item.nodes=item.Childrens;
//处理子节点
if(item.Childrens){
handleChild(item.Childrens);
}
delete item.Id;
delete item.Text;
delete item.Childrens;
}
}
/// <summary>
/// 动态属性转换约定
/// </summary>
/// <remarks>
/// 处理场景 树形结构数据 后台代码实体定义 为 Id Childrens 但是前台树形控件所需数据结构为 id,nodes
/// 这个时候可以使用该属性约定转换类 动态设置 序列化后字段名称
/// </remarks>
/// <example>
/// JsonSerializerSettings setting = new JsonSerializerSettings();
/// setting.ContractResolver = new PropsContractResolver(new Dictionary<string, string> { { "Id", "id" }, { "Text", "text" }, { "Childrens", "nodes" } });
/// string AA = JsonConvert.SerializeObject(cc, Formatting.Indented, setting);
/// </example>
public class PropsContractResolver : DefaultContractResolver
{
Dictionary<string, string> dict_props = null; /// <summary>
/// 构造函数
/// </summary>
/// <param name="props">传入的属性数组</param>
public PropsContractResolver(Dictionary<string, string> dictPropertyName)
{
//指定字段要序列化成什么名称
this.dict_props = dictPropertyName;
} protected override string ResolvePropertyName(string propertyName)
{
string newPropertyName = string.Empty;
if (dict_props != null && dict_props.TryGetValue(propertyName, out newPropertyName))
{
return newPropertyName;
}
else
{
return base.ResolvePropertyName(propertyName);
}
}
}
调用代码实例
string type="zTree";
//字段映射关系
Dictionary<string, string> _dictProp = null;
if(type=="zTree"){
_dictProp = new Dictionary<string, string> { { "Icon", "icon" }, { "Text", "name" }, { "Childrens", "children" } };
}else if(type=="treeview"){
_dictProp = new Dictionary<string, string> { { "Icon", "icon" }, { "Text", "text" }, { "Childrens", "nodes" } };
} // 序列化设置
JsonSerializerSettings PropSettings = new JsonSerializerSettings {
ContractResolver = new PropsContractResolver(_dictProp)
};
return JsonConvert.SerializeObject(new List<Tree>(), Formatting.None, PropSettings);
枚举值序列化问题
默认情况下对于实体里面的枚举类型系统是格式化成改枚举对应的整型数值,那如果需要格式化成枚举对应的字符怎么处理呢?Newtonsoft.Json也帮我们想到了这点,下面看实例
public enum NotifyType
{
/// <summary>
/// Emil发送
/// </summary>
Mail=, /// <summary>
/// 短信发送
/// </summary>
SMS=
} public class TestEnmu
{
/// <summary>
/// 消息发送类型
/// </summary>
public NotifyType Type { get; set; }
}
JsonConvert.SerializeObject(new TestEnmu());
输出结果:
现在改造一下,输出"Type":"Mail"
public class TestEnmu
{
/// <summary>
/// 消息发送类型
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public NotifyType Type { get; set; }
}
其它的都不变,在Type属性上加上了JsonConverter(typeof(StringEnumConverter))表示将枚举值转换成对应的字符串,而StringEnumConverter是Newtonsoft.Json内置的转换类型,最终输出结果

全局设置
全局参数设置功能是我最喜欢使用的功能,现在做的mvc项目,我都会先设定空值处理,减少不必要的流量损耗。上篇文章开篇说了,最初研究Newtonsoft.Json是从移动端项目开始的,无用字段空值字段不返回。
Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();
JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
{
//日期类型默认格式化处理
setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
setting.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //空值处理
setting.NullValueHandling = NullValueHandling.Ignore;return setting;
});
总结
另外有关自定义类型转换问题可以参考Newtonsoft.Json高级用法第九条。序列化库深入使用之后,由衷的佩服作者,可以将一个序列化库做的如此强大,在学习它源代码的同时对自己代码设计理念也产生了很大的影响。感谢Newtonsoft.Json,后续有好的问题会在本篇文章进行续写。
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。
如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。
因为,我的写作热情也离不开您的肯定支持。
感谢您的阅读,如果您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是焰尾迭 。
再谈Newtonsoft.Json高级用法的更多相关文章
- Newtonsoft.Json高级用法之枚举中文转义
最近看博客园中 焰尾迭的两篇关于"Newtonsoft.Json高级用法"的文章受到了很多人的评论,一度登入到头条推荐. 今天我就不再重复焰尾迭博文中的一些提过的Newtonsof ...
- Newtonsoft.Json高级用法(转)
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- 【转】 Newtonsoft.Json高级用法
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- Newtonsoft.Json 高级用法
基本用法 Json.NET是支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity的.下面分别举例说明序列化和反序列化. DataTable: //序列 ...
- 转:Newtonsoft.Json高级用法
原文地址:http://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多 ...
- Newtonsoft.Json高级用法DataContractJsonSerializer,JavaScriptSerializer 和 Json.NET即Newtonsoft.Json datatable,dataset,modle,序列化
原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html Newtonsoft.Json介绍 在做开发的时候,很多数据交换都是以json格式传输的.而 ...
- Newtonsoft.Json高级用法,json序列号,model反序列化,支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity,字符串
原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口 ...
- 【Json】Newtonsoft.Json高级用法
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
随机推荐
- ASP.NET MVC+EF框架+EasyUI实现权限管理系列(22)-为用户设置角色
ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇) (1):框架搭建 (2):数据库访问层的设计Demo (3):面向接口编程 (4 ):业务逻辑层的封装 ...
- js正则表达式图形化工具-rline
github地址:https://github.com/finance-sh/rline 在线demo: http://lihuazhai.com/demo/test.html 这是一个js正则表达式 ...
- 关于在线编辑器的选择:tinymce - nilcms
一开始使用的是百度开发的编辑器:ueditor.使用方便,很容易就部署了.现在发现此编辑器也就做一些安全性的更新,而且对于这个编辑器也越来越不喜欢了. 1.臃肿.[1.4.3.3 PHP 版本].下载 ...
- 政府应急平台之GIS一张图-flex/java
开发语言是flex.java,开发平台是myeclise.eclise,后台数据库是oracel或sqlserver,开发接口是arcgis api for flex,提供以下的功能: 1.视频监控: ...
- 关于json序列化循环引用导致出错
以下是错误信息: Caused by: java.lang.IllegalStateException: circular reference error Offending field: meth ...
- Python之Mac上搭建集成开发环境
首先下载一个东西: 找到下载地址:https://download.jetbrains.8686c.com/python/pycharm-professional-2016.2.1.dmg pycha ...
- easyui窗口组件
注意首先要在title后面导入配置文件,前后顺序不能乱 <!-- 1.JQuery的js包 --><script type="text/javascript" s ...
- Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理6
接下来先做角色这一板块的(增删改查),首先要新建一个Role控制器,在添加一个RoleList的视图.表格打算采用的是bootstrap的表格. using System; using System. ...
- js输出二维数组最长的子数组
,,],[,,,],[,,,,]]; ].length; ; i < a.length; i++) { if (max<a[i].length) { max=a[i].length; va ...
- JavaScript根据文件名判断文件类型
//JavaScript根据文件名判断文件类型 var imgExt = new Array(".png",".jpg",".jpeg",& ...