使用Newtonsoft.Json进行Json序列化忽略首字母大小写,Json字符串反序列化到子集对象(C#)

一、Json序列化忽略首字母大小写

方法一:使用JsonProperty特性,给类中每个属性增加JsonProperty(propertyName)特性

优点:可以指定任意名称序列化成员,不限于首字母大小写

缺点:此方法需要给每一个需要进行json序列化的对象的每一个成员配置特性,工作量较大

以下为测试类,使用JsonProperty特性示例:

 public class Person
 {
    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("age")]
    public int Age { get; set; }

    [JsonProperty("sex")]
    public string Sex { get; set; }

}

以下为json序列化示例:

var p = new Person(){ Name = "张三", Age = 18, Sex = "男"};
var json = JsonConvert.SerializeObject(p);

方法二:无需设置JsonProperty特性,配置JsonSerializerSettings,使用JsonSerializerSettings将指定对象序列化为JSON字符串(此方法的优缺点正好与方法一互补)

var p = new Person(){ Name = "张三", Age = 18, Sex = "男"};
var setting = new JsonSerializerSettings
{
     ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
};
var json = JsonConvert.SerializeObject(p, setting);

以上两种方式,序列化结果如下:

{"name":"张三","age":18,"sex":"男"}

二、Json字符串反序列化到子集对象

首先还是上面的测试对象Person,我们给他属性,并且建个新类继承Person。

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Sex { get; set; }
    public Vocation Vocation { get; set; }
}

public enum Vocation
{
    Teacher = 1,
    Programmer = 2
}

public class Teacher : Person
{
    public string Subject { get; set; }
}

public class Programmer : Person
{
    public string Language { get; set; }
}

然后定义一个List<Person>的对象,里面存的有Person对象,也有他的子集Teacher等对象用于测试使用。

var list = new List<Person>()
{
    new Person()
    {
        Name = "张三",
        Age = 18,
        Sex = "男"
    },
    new Programmer()
    {
        Name = "李四",
        Age = 18,
        Sex = "女",
        Language = "C#语言",
        Vocation = Vocation.Programmer
    },
    new Teacher()
    {
        Name = "王五",
        Age = 29,
        Sex = "男",
        Subject = "数学老师",
        Vocation = Vocation.Teacher
    }
};

序列化无需特殊处理,直接序列化就好了:

var setting = new JsonSerializerSettings
{
    ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
};
var json = JsonConvert.SerializeObject(list, setting);

序列化结果如下:

 如果按照往常正常逻辑进行反序列化,则得到的结果如下所示,少了李四中的language成员和王五的subject成员:

var obj = JsonConvert.DeserializeObject<List<Person>>(json);   // json为上图中的json字符串

 

重点来了,重点来了,这个时候对于上面的json字符串,如何反序列化得到完整的包含子类的list对象呢?

答:反序列化时使用 public static T DeserializeObject<[Nullable(2)] T>(string value, params JsonConverter[] converters)这个方法,即使用JsonConverter的集合将JSON反序列化为指定的.NET类型。需要创建一个Person转换器,该转换器需要继承JsonConverter,具体看代码:

public class PersonConverter : DataCreationConverter<Person>
{
    protected override Person Create(JObject jObject)
    {
        //判断属性值(关键字)来确认是哪个子类,并创建子类
        if (FieldExists("vocation", jObject, out string type))
        {
            switch (type)
            {
                case "1": return new Teacher();
                case "2": return new Programmer();
                default: return new Person();
            }
        }
        else
        {
            return new Person();
        }
    }

    private bool FieldExists(string fieldName, JObject jObject, out string entityName)
    {
        entityName = jObject[fieldName] == null ? "" : jObject[fieldName].ToString();
        return jObject[fieldName] != null;
    }
}

public abstract class DataCreationConverter<T> : JsonConverter
{
    protected abstract T Create(JObject jObject);

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader,
        Type objectType,
        object existingValue,
        JsonSerializer serializer)
    {
        JObject jObject = JObject.Load(reader);
        // 基于JObject创建目标对象
        T target = Create(jObject);
        // 填充对象属性
        serializer.Populate(jObject.CreateReader(), target);

        return target;
    }

    public override void WriteJson(JsonWriter writer,
        object value,
        JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

person转换器创建好之后,则使用该转换器反序列化json,此json为上面得到的[{"name":"张三","age":18,"sex":"男","vocation":0},{"language":"C#语言","name":"李四","age":18,"sex":"女","vocation":2},{"subject":"数学老师","name":"王五","age":29,"sex":"男","vocation":1}]:

var obj2 = JsonConvert.DeserializeObject<List<Person>>(json, new PersonConverter());

反序列化结果,得到了子集对象:

完整工程代码可免费下载:https://gitee.com/dmtlls/json-utils

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值