首页 > 编程语言 >C#对象转换Json时的一些高级用法

C#对象转换Json时的一些高级用法

时间:2024-07-16 15:42:25浏览次数:9  
标签:set Name get C# Gender 用法 Json Hobby public

[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】

转换后的结果:

{
   "Name" : "Tom",
   "Age": 20
}
[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】

转换后的结果:

{
  "Name": "Tom",
  "Gender": 1,
  "Hobby" :["写生","钓鱼","旅行"]
}

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

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; }
}

转换后的结果:

{
  "名称": "Tom",
  "年龄": 20,
  "Birthday": "2002-01-01",
  "Gender": 1,
  "Hobby" :["写生","钓鱼","旅行"]
}

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

public class PeopleInfo
{
     private 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; }
}

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

转换后的结果:

{
  "Age": 20,
  "Birthday": "2002-01-01",
  "Gender": 1,
  "Hobby" :["写生","钓鱼","旅行"]
}

在private成员属性上标记[JsonProperty]

public class PeopleInfo
{
    [JsonProperty]
    private 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; }
}

转换后的结果:

{
  "Name":null,
  "Age": 20,
  "Birthday": "2002-01-01",
  "Gender": 1,
  "Hobby" :["写生","钓鱼","旅行"]
}

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

上面的例子中,Name字段为Null值,假如实际前后端数据交互中,Null值的数据返回岂不是很没有意义?为此,我们可以设置下,如果值为Null值时,就不进行序列化转换。

public class PeopleInfo
{
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
     private 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; }
}

转换后的结果:

{  
  "Age": 20,
  "Birthday": "2002-01-01",
  "Gender": 1,
  "Hobby" :["写生","钓鱼","旅行"]
}

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

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

private void btnJsonDemo_Click(object sender, EventArgs e)
{
     PeopleInfo p = new PeopleInfo();
     //p.Name = "Tom";   //没有对Name属性赋值,Name值为Null值
     p.Age = 20;
     p.Birthday = DateTime.Now.Date;
     p.Gender = EnumGender.male;
     p.Hobby = new List<string> { "写生", "钓鱼", "旅行" };
JsonSerializerSettings setting = new JsonSerializerSettings(); setting.NullValueHandling = NullValueHandling.Ignore; //设置全局的Null值处理 string json = JsonConvert.SerializeObject(p, setting); this.txtResult.Text = json; }

转换后的结果:

{  
  "Age": 20,
  "Birthday": "2002-01-01",
  "Gender": 1,
  "Hobby" :["写生","钓鱼","旅行"]
}

4. 序列化时枚举值的处理

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

public class PeopleInfo
{      
    private string Name { get; set; }       
    public int Age { get; set; }     
    public DateTime Birthday { get; set; }
    //指定Enum类型的转换方式
    [JsonConverter(typeof(StringEnumConverter))]
    public EnumGender Gender { get; set; }
    public List<string> Hobby { get; set; }
}

public Enum EnumGender 
{
    Woman,
    Male
}

转换后的结果:

{  
  "Age": 20,
  "Birthday": "2002-01-01",
  "Gender": "Male"
  "Hobby" :["写生","钓鱼","旅行"]
}

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

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

还用以前的PeopleInfo 类,稍微改进下:

public class PeopleInfo
{      
    private 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 == "Tom")  //如果名称是Tom,则Name属性不序列化
                return false;
            return true;
    }
}

调用方法:

List<PeopleInfo> list = new List<PeopleInfo>();
PeopleInfo p = new PeopleInfo();
p.Name = "Tom";
p.Age = 20;
p.Birthday = DateTime.Now.Date;
p.Gender = EnumGender.male;
p.Hobby = new List<string> { "写生", "钓鱼", "旅行" };
list.Add(p);
 
PeopleInfo p1 = new PeopleInfo();
p1.Name = "Jack";
p1.Age = 30;
p1.Birthday = DateTime.Now.Date;
p1.Gender = EnumGender.male;
p1.Hobby = new List<string> { "工作" };
ist.Add(p1);
 
string json = JsonConvert.SerializeObject(list);
this.txtResult.Text = json;

转换结果为:

{  
  "Age": 20,
  "Birthday": "2002-01-01",
  "Gender": 1,
  "Hobby" :["写生","钓鱼","旅行"]
},
{  
  "Name":"Jack",
  "Age": 30,
  "Birthday": "2002-01-01",
  "Gender": 1,
  "Hobby" :["工作"]
}

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

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

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);

 

标签:set,Name,get,C#,Gender,用法,Json,Hobby,public
From: https://www.cnblogs.com/lgx5/p/18305370

相关文章

  • C++获取当前毫秒数
    转自https://www.cnblogs.com/c9080/p/17509268.html,在C++11中,可以使用<chrono>头文件中的std::chrono::system_clock类来获取当前时间戳。它提供了多种精度和分辨率的时钟类型,其中最常用的是系统时钟。以下是一个示例程序,演示如何使用std::chrono::system_clock类获取......
  • 使用Spring Boot和Docker实现微服务的部署与扩展
    使用SpringBoot和Docker实现微服务的部署与扩展大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在现代软件开发中,微服务架构被广泛采用,而SpringBoot和Docker是实现微服务架构的两大重要技术。本文将详细介绍如何使用SpringBoot和Docker实现微服务的部署......
  • .NETCORE 使用内置IIS 实现内网IP调试
    1.设置IIS 2. 点开某一条路径,编辑配置文件 3.添加对应IP地址的端口号 4.添加网络映射netshhttpaddurlaclurl=https://192.168.0.157:44394/user=everyonenetshhttpaddurlaclurl=http://192.168.0.157:40880/user=everyone如果添加错了,可以删除netshhtt......
  • 【CTF入门】BUUCTF Crypto刷题(持续更新)
    【CTF入门】BUUCTFCrypto刷题(持续更新)一眼就解密题目介绍如图:我们可以发现加密的字符串由base64编码,因此base64解码后即可解密。什么是base64编码,又应该如何解码呢?base64编码介绍原理:https://www.bilibili.com/video/BV1hk4y1S7PJ?vd_source=69c558b0c7be97607c79afbd75bd1......
  • C. Load Balancing
    原题链接题解找出大于对应平均数的部分。。。code#include<bits/stdc++.h>#definelllonglongusingnamespacestd;constllN=114514;lla[100006];voidsolve(){lln;cin>>n;llsum=0;for(inti=1;i<=n;i++){cin>>a[i];......
  • 新趋势|优先选定通过HACCP与ISO22000认证的校外供餐单位
    原料农药残留超标、使用腐败变质食材加工食品、餐具清洗消毒不达标...近年来,校园食品安全问题频发。食品安全,关乎国计民生,更关乎每一个家庭的切身利益。在校园这一特殊环境中,其重要性更是不言而喻。一直以来,国家对校园食品安全高度重视、严格监管、多错并举,一直在不断加强和......
  • 三大知名向量化模型比较分析——m3e,bge,bce
    先聊聊出处。M3E是MokaMassiveMixedEmbedding的缩写,Moka,此模型由MokaAI训练,开源和评测,训练脚本使用uniem,评测BenchMark使用MTEB-zhMassive,此模型通过千万级(2200w+)的中文句对数据集进行训练Mixed,此模型支持中英双语的同质文本相似度计算,异质文本检索等功......
  • 关于CSRF和SSRF的介绍
    一、CSRF1.简介跨站请求伪造(Cross-SiteRequestForgery,CSRF),也被称为OneClickAttack或者SessionRiding,通常缩写为CSRF,是一种对网站的恶意利用。尽管听起来像XSS,但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的......
  • 把LangChain跑起来的3个方法
    使用LangChain开发LLM应用时,需要机器进行GLM部署,好多同学第一步就被劝退了,那么如何绕过这个步骤先学习LLM模型的应用,对Langchain进行快速上手?本片讲解3个把LangChain跑起来的方法,如有错误欢迎纠正。Langchain官方文档地址:https://python.langchain.com/基......
  • Docker安装kafka
    Docker安装kafka安装之前,先创建一个网络,模式为桥接的方式dockernetworkcreatekafkaBridge--driverbridge只要能保证,zk和kafka能后相互访问就好了,方式随意。注意:使用同网络好于不同网络。虽然理论上Kafka和ZooKeeper可以跨广域网部署,但高延迟的网络连接可能会影响......