2021年1月12日星期二

.NET Core 处理 WebAPI JSON 返回烦人的null为空

前言

      项目开发中不管是前台还是后台都会遇到烦人的null,数据库表中字段允许空值,则代码实体类中对应的字段类型为可空类型Nullable<>,如int?,DateTime?,null值字段序列化返回的值都为null,前台对应字段赋值需要做null值判断,怎么才能全局把null替换为空。

      本文分享WebAPI接口服务统一返回null替换为空的方法。

一、分析问题

      .NET Core中使用Newtonsoft.Json进行序列化,WebAPI接口返回格式通过Startup.cs类全局设置。想是否可以通过配置把null替换为空值?于是找到了Newtonsoft.Json在序列化和反序列化期间如何处理空值和默认值的属性,具体配置代码如下:

 1 public void ConfigureServices(IServiceCollection services) 2 { 3  //配置Mvc + json 序列化 4  services.AddMvc() 5   .AddNewtonsoftJson(options => 6   { 7    //数据格式首字母小写 不使用驼峰 小驼峰firstName 大驼峰 FirstName 8    options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 9    //使用默认方式,不更改元数据的key的大小写10    //options.SerializerSettings.ContractResolver = new DefaultContractResolver();11    // 忽略循环引用12    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;13    // 设置时间格式14    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";15    //忽略空值 不包含属性的null序列化16    //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;17    //忽略默认值和null 1、不包含属性默认值和null18    //options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Igno19   })20 }

 1、空值的处理

      序列化和反序列化时需要忽略值为null的属性,设置SerializerSettings.NullValueHandling的值

  •  NullValueHandling.Ignore 序列化和反序列化对象时忽略空值。
  •  NullValueHandling.Include 序列化和反序列化对象时包含空值。

2、默认值的处理

      序列化和反序列化时需要忽略默认值属性,设置SerializerSettings.DefaultValueHandling的值

  • DefaultValueHandling.Ignore 序列化和反序列化时忽略默认值
  • DefaultValueHandling.Include序列化和反序列化时包含默认值

3、示例代码

 1 /*包含属性的默认值与null序列化*/ 2 { 3 "Name": null, 4 "Age": 0, 5 "Partner": null, 6 "Salary": 0.0 7 } 8 /*不包含属性的默认值序列化*/ 9 {10 "Name": "Hello World",11 "Age": 2812 }13 /*不包含属性的null序列化*/14 {15 "Name": "Hello World",16 "Age": 28,17 "Salary": 0.018 }

通过上面的分析:一种是不包含属性的默认值序列化,另一种是不包含属性的null序列化,都不能满足目前的需求接口统一返回的null序列化为空。

二、解决问题

1、项目WebAPI默认返回的JSON结果格式如下:

 1 { 2 "code": 0, 3 "msg": "查询成功", 4 "data": { 5  "id": 1, 6  "title": "炎炎夏日暖暖肚", 7  "describe": "", 8  "author": null, 9  "authorId": null,10  "linkSource": null,11  "author_Picture": null,12  "content": "炎炎夏日,很多人喜欢吃些寒凉的食物解暑,可这种做法非常伤身。",13  }14 }

2、需要解决的问题把所有的null替换为空,具体如下图所示:

        

3、解决方案

      需要自己写一个NullToEmptyStringResolver类,然后重写CamelCasePropertyNamesContractResolver,但是该方法只能解决string类型null→""的问题,对其他可空类型无效,比如:int?、DateTime?等。

 1 public class NullToEmptyStringResolver : CamelCasePropertyNamesContractResolver 2 { 3  /// <summary> 4  /// 创建属性 5  /// </summary> 6  /// <param name="type">类型</param> 7  /// <param name="memberSerialization">序列化成员</param> 8  /// <returns></returns> 9  protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)10  {11   return type.GetProperties().Select(c =>12     {13      var jsonProperty = base.CreateProperty(c, memberSerialization);14      jsonProperty.ValueProvider = new NullToEmptyStringValueProvider(c);15      return jsonProperty;16     }).ToList();17  }18 }19 20 public class NullToEmptyStringValueProvider : IValueProvider21 {22  private readonly PropertyInfo _memberInfo;23  /// <summary>24  /// 构造函数25  /// </summary>26  /// <param name="memberInfo"></param>27  public NullToEmptyStringValueProvider(PropertyInfo memberInfo)28  {29   _memberInfo = memberInfo;30  }31 32  /// <summary>33  /// 获取Value34  /// </summary>35  /// <param name="target"></param>36  /// <returns></returns>37  public object GetValue(object target)38  {39   var result = _memberInfo.GetValue(target);40   if (_memberInfo.PropertyType == typeof(string) && result == null)41    result = string.Empty;42   return result;43  }44 45  /// <summary>46  /// 设置Value47  /// </summary>48  /// <param name="target"></param>49  /// <param name="value"></param>50  public void SetValue(object target, object value)51  {52   _memberInfo.SetValue(target, value);53  }54 }

      在Startup.cs代码里面修改,标记为红色的代码,如下所示:

 1 //配置MVC+JSON序列化 2 services 3  .AddMvc(options =>{options.EnableEndpointRouting = false;}) 4  .AddNewtonsoftJson(options => 5  { 6   //使用默认方式,不更改元数据的key的大小写 7   //options.SerializerSettings.ContractResolver = new DefaultContractResolver(); 8   //数据格式首字母小写 不使用驼峰 小驼峰firstName 大驼峰 FirstName 9   //options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();10   options.SerializerSettings.ContractResolver = new NullToEmptyStringResolver();11   // 忽略循环引用12   options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;13   // 设置时间格式14   options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";15   //忽略空值 不包含属性的null序列化16   //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;17   //忽略默认值和null 1、不包含属性默认值和null 18   //options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Igno19  })

      修改完配置,重新运行完成,实现null替换为空的效果,运行结果如下所示:

 1 { 2 "code": 0, 3 "msg": "查询成功!", 4 "data": { 5  "id": 1, 6  "title": "炎炎夏日暖暖肚", 7  "describe": "", 8  "author": "", 9  "authorId": "",10  "linkSource": "",11  "author_Picture": "",12  "source": 0,13  "content": "炎炎夏日,很多人喜欢吃些寒凉的食物解暑,可这种做法非常伤身。"14  }15 }

三、总结

      .NET Core下Newtonsoft.Json序列化时字符串null替换成空,通过ContractResolver类为属性添加一些序列化设置、自定义属性名、设置时间格式、有选择性的序列化属性等,实现WebAPI返回JSON格式统一化。

 

优秀是一种习惯,欢迎大家关注学习  

 









原文转载:http://www.shaoqun.com/a/508508.html

跨境电商:https://www.ikjzd.com/

新单:https://www.ikjzd.com/w/79

汇通天下:https://www.ikjzd.com/w/2055


前言项目开发中不管是前台还是后台都会遇到烦人的null,数据库表中字段允许空值,则代码实体类中对应的字段类型为可空类型Nullable<>,如int?,DateTime?,null值字段序列化返回的值都为null,前台对应字段赋值需要做null值判断,怎么才能全局把null替换为空。本文分享WebAPI接口服务统一返回null替换为空的方法。一、分析问题.NETCore中使用Newto
tradekey:tradekey
pocket:pocket
桃园有哪些值得购买的地方特产:桃园有哪些值得购买的地方特产
2020年七夕是什么时候?:2020年七夕是什么时候?
口述:结婚前夕 得知女友不清白怎么办:口述:结婚前夕 得知女友不清白怎么办

没有评论:

发表评论