Newtonsoft.Json 用法

  1. 忽略某些属性
  2. 默认值的处理
  3. 空值的处理
  4. 支持非公共成员
  5. 日期处理
  6. 自定义序列化的字段名称
  7. 动态决定属性是否序列化
  8. 枚举值的自定义格式化问题
  9. 自定义类型转换
  10. 全局序列化设置

1.忽略某些属性

我们在序列化的过程中,并不是所有属性都需要序列化的,如果实体中有些属性不需要序列化,可以使用该特性。首先介绍 Json.Net序列化的模式: OptOutOptIn

模式说明 OptOut 默认值,类中所有公有成员会被序列化,如果不想被序列化,可以用特性 JsonIgnore OptIn 默认情况下,所有的成员不会被序列化,类中的成员只有标有特性 JsonProperty的才会被序列化,当类的成员很多,但客户端仅仅需要一部分数据时,很有用

仅需要姓名属性

[JsonObject(MemberSerialization.OptIn)]
public class Person
{
    public int Age { get; set; }
    [JsonProperty]
    public string Name { get; set; }
    public string Sex { get; set; }
    public bool IsMarry { get; set; }
    public DateTime Birthday { get; set; }
}

Newtonsoft.Json 用法

不需要是否结婚属性

[JsonObject(MemberSerialization.OptOut)]
public class Person
{
    public int Age { get; set; }
    public string Name { get; set; }
    public string Sex { get; set; }
    [JsonIgnore]
    public bool IsMarry { get; set; }
    public DateTime Birthday { get; set; }
}

Newtonsoft.Json 用法

通过上面的例子可以看到,要实现不返回某些属性的需求很简单:

  1. 在实体类上加上 [JsonObject(MemberSerialization.OptOut)]
  2. 在不需要返回的属性上加上 [JsonIgnore]说明。

2.默认值处理

序列化时想忽略默认值属性可以通过 JsonSerializerSettings.DefaultValueHandling来确定,该值为枚举值

枚举值说明 DefaultValueHandling.Ignore 序列化和反序列化时,忽略默认值 DefaultValueHandling.Include 序列化和反序列化时,包含默认值

[DefaultValue(10)]
public int Age { get; set; }

Person p = new Person
{
    Age = 10,
    Name = "张三丰",
    Sex = "男",
    IsMarry = false,
    Birthday = new DateTime(1991, 1, 2)
};
JsonSerializerSettings jsetting = new JsonSerializerSettings();
jsetting.DefaultValueHandling = DefaultValueHandling.Ignore;
Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

最终结果如下:

Newtonsoft.Json 用法

3.空值的处理

序列化时需要忽略值为 NULL的属性,可以通过 JsonSerializerSettings.NullValueHandling来确定,另外通过 JsonSerializerSettings设置属性是对序列化过程中所有属性生效的,想单独对某一个属性生效可以使用 JsonProperty,下面将分别展示两个方式

1)JsonSerializerSettings

Person p = new Person
{
    room = null,
    Age = 10,
    Name = "张三丰",
    Sex = "男",
    IsMarry = false,
    Birthday = new DateTime(1991, 1, 2)
};
JsonSerializerSettings jsetting = new JsonSerializerSettings();
jsetting.NullValueHandling = NullValueHandling.Ignore;
Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

Newtonsoft.Json 用法

2)JsonProperty

Newtonsoft.Json 用法

通过 JsonProperty属性设置的方法,可以实现某一属性特别处理的需求,如默认值处理,空值处理,自定义属性名处理,格式化处理。上面空值处理实现

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Room room { get; set; }

4.支持非公共成员

序列化时默认都是处理公共成员,如果需要处理非公共成员,就要在该成员上加特性 [JsonProperty]

[JsonProperty]
private int Height { get; set; }

5.日期处理

对于 Dateime类型日期的格式化就比较麻烦了,系统自带的会格式化成 iso日期标准 "Birthday":"1991-01-02T00:00:00,但是实际使用过程中大多数使用的可能是 yyyy-MM-dd或者 yyyy-MM-dd HH:mm:ss两种格式的日期,解决办法是可以将 DateTime类型改成 string类型自己格式化好,然后再序列化。如果不想修改代码,可以采用下面方案实现。

Json.Net提供了 IsoDateTimeConverter日期转换这个类,可以通过 JsnConverter实现相应的日期转换

[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime Birthday { get; set; }

但是 IsoDateTimeConverter日期格式不是我们想要的,我们可以继承该类实现自己的日期

public class ChinaDateTimeConverter : DateTimeConverterBase
{
    private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" };
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        return dtConverter.ReadJson(reader, objectType, existingValue, serializer);
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        dtConverter.WriteJson(writer, value, serializer);
    }
}

自己实现了一个 yyyy-MM-dd格式化转换类,可以看到只是初始化 IsoDateTimeConverter时给的日期格式为 yyyy-MM-dd即可,下面看下效果

[JsonConverter(typeof(ChinaDateTimeConverter))]
public DateTime Birthday { get; set; }

Newtonsoft.Json 用法

可以根据自己需求实现不同的转换类

6.自定义序列化的字段名称

实体中定义的属性名可能不是自己想要的名称,但是又不能更改实体定义,这个时候可以自定义序列化字段名称。

[JsonProperty(PropertyName = "CName")]
public string Name { get; set; }

7.动态决定属性是否序列化

根据某些场景,可能 A场景输出 ABC三个属性, B场景输出 EF属性。虽然实际中不一定存在这种需求,但是 json.net依然可以支持该特性。

继承默认的 DefaultContractResolver类,传入需要输出的属性

重写修改了一下,大多数情况下应该是要排除的字段少于要保留的字段, 为了方便书写这里修改了构造函数加入 retain表示 props是需要保留的字段还是要排除的字段

public class LimitPropsContractResolver : DefaultContractResolver
{
    string[] props = null;
    bool retain;

public int Age { get; set; }
[JsonIgnore]
public bool IsMarry { get; set; }
public string Sex { get; set; }

JsonSerializerSettings jsetting = new JsonSerializerSettings();
jsetting.ContractResolver = new LimitPropsContractResolver(new string[] { "Age", "IsMarry" });
Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

使用自定义的解析类,只输出 AgeIsMarry两个属性,看下最终结果。只输出了 Age属性,为什么 IsMarry属性没有输出呢,因为标注了 [JsonIgnore]

Newtonsoft.Json 用法

看到上面的结果想要实现 pc端序列化一部分,手机端序列化另一部分就很简单了吧,我们改下代码实现一下

string[] propNames = null;
if (p.Age > 10)
{
    propNames = new string[] { "Age", "IsMarry" };
}
else
{
    propNames = new string[] { "Age", "Sex" };
}
jsetting.ContractResolver = new LimitPropsContractResolver(propNames);
Console.WriteLine(JsonConvert.SerializeObject(p, Formatting.Indented, jsetting));

8.枚举值的自定义格式化问题

默认情况下对于实体里面的枚举类型系统是格式化成改枚举对应的整型数值,那如果需要格式化成枚举对应的字符怎么处理呢? Newtonsoft.Json也帮我们想到了这点,下面看实例

public enum NotifyType
{

Newtonsoft.Json 用法

现在改造一下,输出 "Type":"Mail"

public class TestEnmu
{

其它的都不变,在 Type属性上加上了 JsonConverter(typeof(StringEnumConverter))表示将枚举值转换成对应的字符串,而 StringEnumConverterNewtonsoft.Json内置的转换类型,最终输出结果

Newtonsoft.Json 用法

9.自定义类型转换

默认情况下对于实体里面的 Boolean系统是格式化成 true或者 false,对于 true转成”是” false转成”否”这种需求改怎么实现了?我们可以自定义类型转换实现该需求,下面看实例

public class BoolConvert : JsonConverter
{
    private string[] arrBString { get; set; }

    public BoolConvert()
    {
        arrBString = "是,否".Split(',');
    }

自定义了 BoolConvert类型,继承自 JsonConverter。构造函数参数 BooleanString可以让我们自定义将 true false转换成相应字符串。下面看实体里面怎么使用这个自定义转换类型

public class Person
{
    [JsonConverter(typeof(BoolConvert))]
    public bool IsMarry { get; set; }
}

Newtonsoft.Json 用法

相应的有什么个性化的转换需求,都可以使用自定义转换类型的方式实现。

10.全局序列化设置

文章开头提出了 Null值字段怎么不返回的问题,相应的在高级用法也给出了相应的解决方案使用 jsetting.NullValueHandling = NullValueHandling.Ignore;来设置不返回空值。这样有个麻烦的地方,每个不想返回空值的序列化都需设置一下。可以对序列化设置一些默认值方式么?下面将解答

Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings();
JsonConvert.DefaultSettings = new Func(() => {

这样设置以后,以后使用序列化的地方就不需要单独设置了

Original: https://www.cnblogs.com/zeroone/p/15887244.html
Author: 武胜-阿伟
Title: Newtonsoft.Json 用法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/554420/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球