三:C#对象转换Json时的一些高级(特殊)设置;
导航目录:
一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型;
二:C#对象、集合、DataTable与Json内容互转示例;
前面两篇分别介绍了C#转换JSON时一些常规的用法,以前我也是,只用到了前面这些比较常用的方法,没想到在转换时还有那么多特殊的设置,
今天这篇内容就来讲一下一些特殊的设置,比如,转换时过滤掉个别属性、重命名字段名称、枚举字段的处理、私有变量的转换等;
好了,开始今天的正题:
序列化时忽略特定的属性字段
需求分析:有时候在前后台或者APP直接进行数据交互的时候,不需要全部的属性内容,举个栗子,比如,只想知道用户的名字叫啥,如果把用户的年龄、
性别,爱好都返回,中间的传输过程就会占用宽带,而且,其它的字段也不需要,也浪费了转换的性能。SO,还是前面文章中的对象类,咱们改进下,比
如,现在我们只想要这个用户的名字叫啥,代码怎么改呢?
有两种方式可以实现,方式1:比如你去饭店,告诉老板我要这个菜,这个菜,还有那个菜。
[JsonObject(MemberSerialization.OptIn)] //这个标签定义了你的选菜方式,只选我要的
public class PeopleInfo
{ [JsonProperty] //这个标签标记了这个是你要选择的菜品 public string Name { get; set; } [JsonProperty] //这个标签标记了这个是你要选择的菜品 public int Age { get; set; } public DateTime Birthday { get; set; } public EnumGender Gender { get; set; } public List<string> Hobby { get; set; } }
【OptIn情况下,默认是将所有的属性都定义成了不要,如果这个属性需要转换成Json,需要标记JsonProperty】
转换后的结果:
方式2:就是你去饭店,告诉老板我不要这个菜,不要这个菜。
[JsonObject(MemberSerialization.OptOut)] //这个标签定义了你的选菜方式,排除我不要的
public class PeopleInfo
{
public string Name { get; set; } [JsonIgnore] //这个标签标记了这个不是要想要的菜品
public int Age { get; set; }
[JsonIgnore] //这个标签标记了这个不是要想要的菜品
public DateTime Birthday { get; set; }
public EnumGender Gender { get; set; }
public List<string> Hobby
{ get; set; }
}
【OptOut情况下,默认是将所有的属性都定义成了要转换Json,如果这个属性不需要转换成Json,需要标记JsonIgnore】
序列化时更改(重命名)属性名称;
需求分析:有时候实体类中定义的属性名称可能不是想要的名称,但是又不能更改实体类中属性的名称,这个时候就可以自定义序列化字段名称。
这就好比,饭店里面的一道菜菜单叫蚂蚁上树,实际上就是一道粉丝炒肉末,蚂蚁上树就是重命名的属性名称,粉丝炒肉末才是它的实体类名称;
还是复用前面的代码,稍微修改下:
public class PeopleInfo
{
[JsonProperty(PropertyName = "名称")] //写法1
public string Name { get; set; }
[JsonProperty("年龄")] //写法2
public int Age { get; set; }
public DateTime Birthday { get; set; }
public EnumGender Gender { get; set; }
public List<string> Hobby
{ get; set; }
}
转换后的结果:
序列化时将非公共变量(private)转换为Json;
分析:一般情况下,在进行Json转换的时候,只会对public 成员进行Json转换,默认情况下,私有成员是不转换的。
只需要在属性上标记[JsonProperty]就可以了。如下图:
序列化时忽略空值的属性字段;
分析:上上面的例子中,Name字段为Null值,假如实际前后端数据交互中,Null值的数据返回岂不是很没有意义?为此,我们
可以设置下,如果值为Null值时,就不进行序列化转换。
方式1:在属性成员中指定NullValueHandling方式。
【NullValueHandling:这是每个枚举值,Ignore忽略空值,Include包含空值】
方式2:通过上面的示例,我们可以发现,可以对单个属性进行设置,如果一个实体类有20个属性成员,30个属性成员,然后,
一个一个去设置岂不是很二,有没有更高效的方式呢?答案是当然有的啦,看下面,这个方式就不需要在单独对每一个属性进行设置了。
代码:
private void btnJsonDemo_Click(object sender, EventArgs e)
{
PeopleInfo p = new PeopleInfo();
//p.Name = "李家村的二狗子"; //没有对Name属性赋值,Name值为Null值
p.Age = 30;
p.Birthday = DateTime.Now;
p.Gender = EnumGender.male;
p.Hobby = new List<string> { "写Bug", "钓鱼", "看新闻联播" }; JsonSerializerSettings setting = new JsonSerializerSettings();
setting.NullValueHandling = NullValueHandling.Ignore; //设置全局的Null值处理,JsonSerializerSettings竟然没有构造函数,一点都不OOP
string json = JsonConvert.SerializeObject(p, setting);
this.txtResult.Text = json;
}
转换结果如下图:
序列化时枚举值的处理;
分析:在上面的例子中,所转换的Gender都是int类型的,假如,我们在转换Json时需要转换成对应的字符怎么操作呢?
代码:[JsonConverter(typeof(StringEnumConverter))]
根据条件来设置属性是否序列化;
Json.NET能够通过在类上放置ShouldSerialize方法来有条件地序列化属性,要有条件地序列化属性,需要在对象类中增加一个
与该属性同名的布尔值的方法,然后使用ShouldSerialize作为方法名称的前缀,比如你要设置属性字段Name根据条件来动态决
定是否序列化,则方法名一定要写成ShouldSerializeName()。方法的返回值必须是bool类型,如果返回true,表示这个属性可以
序列化,返回false表示不被序列化。
还用以前的PeopleInfo 类,稍微改进下:
public class PeopleInfo
{
public string Name { get; set; }
public int Age { get; set; }
public DateTime Birthday { get; set; }
public EnumGender Gender { get; set; } public List<string> Hobby { get; set; } //注意方法名称以及方法类型
public bool ShouldSerializeName()
{
if (this.Name == "李四") //如果名称是李四,则Name属性不序列化
return false;
return true;
}
}
调用方法:
List<PeopleInfo> list = new List<PeopleInfo>();
PeopleInfo p = new PeopleInfo();
p.Name = "李二狗";
p.Age = 30;
p.Birthday = DateTime.Now;
p.Gender = EnumGender.male;
p.Hobby = new List<string> { "写Bug", "钓鱼", "看新闻联播" };
list.Add(p); PeopleInfo p1 = new PeopleInfo();
p1.Name = "李四";
p1.Age = 30;
p1.Birthday = DateTime.Now;
p1.Gender = EnumGender.male;
p1.Hobby = new List<string> { "工作" };
list.Add(p1); string json = JsonConvert.SerializeObject(list);
this.txtResult.Text = json;
转换结果如下图:
问题升级:如果需要两个或者多个属性都可以根据条件来序列化?难道要写很多个方法?
根据条件来设置多个属性是否序列化;
针对上面的问题,如果有多个属性需要根据条件来序列化怎么办?我们可以新增一个方法,如下:
public class LimitPropsContractResolver : DefaultContractResolver
{
string[] Propertys = null;
bool IsSerialize;
public LimitPropsContractResolver(string[] props, bool retain = true)
{
this.Propertys = props;
this.IsSerialize = retain;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
return list.Where(p =>
{
if (IsSerialize)
{
return Propertys.Contains(p.PropertyName);
}
else
{
return !Propertys.Contains(p.PropertyName);
}
}).ToList();
}
}
调用的时候,只需要把字段名称传入string数组中就可以,bool值表示是否需要转换此字段;调用方法如下:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new LimitPropsContractResolver(new string[] { "Gender", "Hobby" }, false);
string json = JsonConvert.SerializeObject(list, settings);
参考:
官方:https://github.com/JamesNK/Newtonsoft.Json
官方文档:https://www.newtonsoft.com/json/help/html/Introduction.htm
https://www.cnblogs.com/leonsky/p/3300511.html
http://www.cnblogs.com/yanweidie/p/4605212.html#_label2
感谢官方以及部分原文作者。
三:C#对象转换Json时的一些高级(特殊)设置;的更多相关文章
- spring boot @ResponseBody转换JSON 时 Date 类型处理方法,Jackson和FastJson两种方式,springboot 2.0.9配置fastjson不生效官方解决办法
spring boot @ResponseBody转换JSON 时 Date 类型处理方法 ,这里一共有两种不同解析方式(Jackson和FastJson两种方式,springboot我用的1.x的版 ...
- Java对象转JSON时如何动态的增删改查属性
1. 前言 日常开发中少不了JSON处理,少不了需要在JSON中添加额外字段或者删除特定字段的需求.今天我们就使用Jackson类库来实现这个功能. 2. JSON字符串增加额外字段 假如我们有这样结 ...
- FastJson、Jackson、Gson进行Java对象转换Json细节处理
前言 Java对象在转json的时候,如果对象里面有属性值为null的话,那么在json序列化的时候要不要序列出来呢?对比以下json转换方式 一.fastJson 1.fastJson在转换java ...
- FastJson、Jackson、Gson进行Java对象转换Json的细节处理
前言 Java对象在转json的时候,如果对象里面有属性值为null的话,那么在json序列化的时候要不要序列出来呢?对比以下json转换方式 一.fastJson 1.fastJson在转换java ...
- 对象转Json时,Date类型格式化问题
object是一个对象,该对象中有一个字段为Date类型 使用JSONObject obj = JSONObject.fromObject(object);将Object转成json时 Date类型字 ...
- NewtonSoft对象转json时,把 NULL 转 "" , 过滤 NULL, DateTime 时间类型去除 T
IsoDateTimeConverter timeConverter = new IsoDateTimeConverter(); timeConverter.DateTimeFormat = &quo ...
- Java对象转换Json的细节处理
一.fastJson 1.fastJson在转换java对象为json的时候,默认是不序列化null值对应的key的 也就是说当对象里面的属性为空的时候,在转换成json时,不序列化那些为null值的 ...
- JAVA对象转换JSON
1. 把java 对象列表转换为json对象数组,并转为字符串 复制代码 代码如下: JSONArray array = JSONArray.fromObject(userlist); String ...
- 解决使用JavaScriptConvert转换对象为Json时,中文和&符号被转码的问题
描述:比如 对象为var data=new {url="http://www.baidu.com?a=b&c=d"} 使用JavaScriptConvert序列化为JSON ...
随机推荐
- Item 22: 当使用Pimpl机制时,在实现文件中给出特殊成员函数的实现
本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 如果你曾经同过久的编译时间斗争过,那么你肯定对Pi ...
- python实战案例--银行系统
stay hungry, stay foolish.求知若饥,虚心若愚. 今天和大家分享一个python的实战案例,很多人在学习过程中都希望通过一些案例来试一下,也给自己一点动力.那么下面介绍一下这次 ...
- Jvm 参数笔记
Jvm参数含义 https://cloud.tencent.com/developer/article/1129474 从一道题说起 https://blog.csdn.net/crazylzxlzx ...
- Final Destination II -- 矩阵快速幂模板题
求f[n]=f[n-1]+f[n-2]+f[n-3] 我们知道 f[n] f[n-1] f[n-2] f[n-1] f[n-2] f[n-3] 1 1 ...
- elasticsearch elk最全java api 搜索 聚合、嵌套查询
目录 一. 一般查询... 2 (一) matchAllQuery(client). 2 (二) matchQuery(client);3 (三) multiMatchQuery(client);3 ...
- Python“Non-ASCII character 'xe5' in file”报错问题
今天在编译一个Python程序的时候,一直出现“Non-ASCII character 'xe5' in file”报错问题 SyntaxError: Non-ASCII character '\xe ...
- Shell脚本命令图片
查看相关文档:shell脚本1 shell脚本2
- CentOS7安装k8s
借鉴博客:https://www.cnblogs.com/xkops/p/6169034.html 此博客里面有每个k8s配置文件的注释:https://blog.csdn.net/qq_359048 ...
- PhpStorm 配置链接远程虚拟机
安装好了 PhpStorm 之后,打开项目文件夹,接着点击工具栏 Tools: 2.接着点击 tools>Deployment: 3.点击Configuration 开始配置 4.填好箭头 ...
- 认识SQL
一.SQL介绍 SQL 是用于访问和处理数据库的标准的计算机语言. i.What? SQL 指结构化查询语言 SQL 使我们有能力访问数据库 SQL 是一种 ANSI 的标准计算机语言 ii.How? ...