前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Newtonsoft.Json

Newtonsoft.Json

作者头像
邹金全
修改2023-04-22 18:44:05
2.4K0
修改2023-04-22 18:44:05
举报
文章被收录于专栏:常用

开发过程中通常会使用Json进行数据交互,C#语言中会使用到Newtonsoft.Json.dll 这个类库,这个类库是开源类库,虽然类库非微软官方,但是被广泛使用;

源码地址:https://github.com/JamesNK/Newtonsoft.Json 官网文档:https://www.newtonsoft.com/json/help/html/Introduction.htm

.net 对象类型支持序列化与反序列化

.net 对象类型

转换后的Json 类型

IList, IEnumerable, IList<T>, Array,datatable

json数组

IDictionary, IDictionary<TKey, TValue>

json对象

Object (more detail below)

json对象

.net 属性类型

转换后的Json类型

String

String

Byte、sbyte、uint16、uint32、int32、uint64、int64

Integer

Float、double、decimal

Float

Enum

Integer

Datetime

String

Byte[]

string

Type

String(类型名称)

Guid

string

typeConverter

string

C#对象、集合、DataTable与Json内容互转示例

代码语言:javascript
复制
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; }
}

PeopleInfo p = new PeopleInfo();
p.Name = "张三十";
p.Age = 30;
p.Birthday = DateTime.Now;
p.Gender = EnumGender.male;
p.Hobby = new List<string> { "音乐", "跑步", "看电影" };
string json = JsonConvert.SerializeObject(p);
this.txtResult.Text = json;

序列化操作后的Josn内容
{
    "Name": "张三十",
    "Age": 30,
    "Birthday": "2022-01-09T17:55:39.8176013+08:00",
    "Gender": 1,
    "Hobby": ["音乐", "跑步", "看电影"]
};

List集合转Json示例

代码语言:javascript
复制
            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> { "音乐", "跑步", "看电影" };

            PeopleInfo p1 = new PeopleInfo();
            p1.Name = "王五";
            p1.Age = 30;
            p1.Birthday = DateTime.Now;
            p1.Gender = EnumGender.male;
            p1.Hobby = new List<string> { "读书", "写字", "打游戏" };
            list.Add(p);
            list.Add(p1);
            string json = JsonConvert.SerializeObject(list);//转成后的Josn字串

Json 转C# 对象 示例

代码语言:javascript
复制
string json = "{\"Name\":\"张三十\",\"Age\":30,\"Birthday\":\"2022-01-19T17:55:39.8176013+08:00\",\"Gender\":1,\"Hobby\":[\"音乐\",\"跑步\",\"看电影\"]}";            
PeopleInfo info = JsonConvert.DeserializeObject<PeopleInfo>(json);//转为了PeopleInfo 对象

Json 转键值对 示例

代码语言:javascript
复制
string json = @“{” “姓名” “:” “张三” “,” “年龄” “:” “30” “}” ; 
  Dictionary < string,string > values = JsonConvert.DeserializeObject <Dictionary < string,string >>(json);

DataTable转Json 示例: 代码略,方法一样的,把DataTable传入至 JsonConvert.SerializeObject(DataTable tb)

C#对象转换Json时的一些高级(特殊)设置

前面这些比较常用的方法,转换时还有许多特殊的设置,

下面讲一下一些特殊的设置,比如,转换时过滤掉个别属性、重命名字段名称、枚举字段的处理、私有变量的转换等;

序列化时忽略特定的属性字段

需求分析:数据交互时有时候不需要全部的属性内容,如只需要PeopleInfo里面的姓名和年龄不需要性别和爱好,不过滤掉在交互过程中就会占用带宽和浪费转换的性能,

代码改进

方法一:

代码语言:javascript
复制
 [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】

转换后的

代码语言:javascript
复制
{
     ” Name“:”张三十“,
     ” Age“:”30“
}

方法二:

代码语言:javascript
复制
 [JsonObject(MemberSerialization.OptOut)]   //这个标签定义了你的过滤属性方式,【排除我不要的】
 public class PeopleInfo
 {
    public string Name { get; set; }
    [JsonIgnore]   //这个标签标记了这个是排除不要
    public int Age { get; set; }
    [JsonIgnore]   //这个标签标记了这个是排除不要
    public DateTime Birthday { get; set; }
    [JsonIgnore]   //这个标签标记了这个是排除不要
    public EnumGender Gender { get; set; }
    public List<string> Hobby{ get; set; }
}

【OptOut情况下,默认是将所有的属性都定义成了要转换Json,如果这个属性不需要转换成Json,需要标记JsonIgnore】

转换后的Josn

代码语言:javascript
复制
{
     ” Name“:”张三十“,
     ” Hobby“:["音乐","跑步","看电影"]
}

序列化时更改(重命名)属性名称

需求分析:有时候实体类中定义的属性名称可能不是想要的名称,但是又不能更改实体类中属性的名称,这个时候就可以自定义序列化字段名称。

代码语言:javascript
复制
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; }
 }
//转换后的结果
{
     ” 姓名“:”张三十“,
     ” 年龄“:”30“
     ” Birthday“:”张三十“,
      "Gender" : 1;
     ” Hobby“:["音乐","跑步","看电影"]
}

序列化时将非公共变量(private)转换为Json

分析:一般情况下,在进行Json转换的时候,只会对public 成员进行Json转换,默认情况下,私有成员是不转换的。

只需要在属性上标记[JsonProperty]就可以了。如下图:

序列化时忽略空值的属性字段

分析:上上面的例子中,Name字段为Null值,假如实际前后端数据交互中,Null值的数据返回岂不是很没有意义?为此,我们

可以设置下,如果值为Null值时,就不进行序列化转换。

方式1:在属性成员中指定NullValueHandling方式。

【NullValueHandling:这是每个枚举值,Ignore忽略空值,Include包含空值】

方式2:通过上面的示例,我们可以发现,可以对单个属性进行设置,如果一个实体类有20个属性成员,30个属性成员,然后,一个一个去设置很麻烦,有没有更高效的方式呢?看下面,这个方式就不需要在单独对每一个属性进行设置了。

代码语言:javascript
复制
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); 

转换结果如下图:

序列化时枚举值的处理

分析:在上面的例子中,所转换的Gender都是int类型的,假如,我们在转换Json时需要转换成对应的字符怎么操作?

代码:[JsonConverter(typeof(StringEnumConverter))]

根据条件来设置属性是否序列化

Json.NET能够通过在类上放置ShouldSerialize方法来有条件地序列化属性,要有条件地序列化属性,需要在对象类中增加一个与该属性同名的布尔值的方法,然后使用ShouldSerialize作为方法名称的前缀,比如你要设置属性字段Name根据条件来动态决定是否序列化,则方法名一定要写成ShouldSerializeName()。方法的返回值必须是bool类型,如果返回true,表示这个属性可以序列化,返回false表示不被序列化。

代码语言:javascript
复制
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;
 }
}

调用方法:

代码语言:javascript
复制
            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);
 

转换结果如下图:

问题升级:如果需要两个或者多个属性都可以根据条件来序列化?难道要写很多个方法?

根据条件来设置多个属性是否序列化

针对上面的问题,如果有多个属性需要根据条件来序列化怎么办?我们可以新增一个方法,如下:

代码语言:javascript
复制
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值表示是否需要转换此字段;调用方法如下:

代码语言:javascript
复制
JsonSerializerSettings settings = new JsonSerializerSettings();
            settings.ContractResolver = new LimitPropsContractResolver(new string[] { "Gender", "Hobby" }, false);
            string json = JsonConvert.SerializeObject(list, settings);

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • .net 对象类型支持序列化与反序列化
  • C#对象、集合、DataTable与Json内容互转示例
    • List集合转Json示例
      • Json 转C# 对象 示例
      • C#对象转换Json时的一些高级(特殊)设置
        • 序列化时更改(重命名)属性名称
          • 序列化时将非公共变量(private)转换为Json
            • 序列化时忽略空值的属性字段
              • 序列化时枚举值的处理
                • 根据条件来设置属性是否序列化
                  • 根据条件来设置多个属性是否序列化
                  相关产品与服务
                  文件存储
                  文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档