前言

项目开发中不管是前台还是后台都会遇到烦人的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、不包含属性默认值和null
18 //options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Igno
19 })
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": 28
12 }
13 /*不包含属性的null序列化*/
14 {
15 "Name": "Hello World",
16 "Age": 28,
17 "Salary": 0.0
18 }

通过上面的分析:一种是不包含属性的默认值序列化,另一种是不包含属性的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 : IValueProvider
21 {
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 /// 获取Value
34 /// </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 /// 设置Value
47 /// </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.Igno
19 })

修改完配置,重新运行完成,实现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格式统一化。

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

.NET Core 处理 WebAPI JSON 返回烦人的null为空的更多相关文章

  1. 【转】【Stackoverflow好问题】去掉烦人的“!=null"(判空语句)

    [Stackoverflow好问题]去掉烦人的“!=null"(判空语句) 问题 为了避免空指针调用,我们经常会看到这样的语句   ...if (someobject != null) { ...

  2. ASP.NET Core API 接收参数去掉烦人的 [FromBody]

    在测试ASP.NET Core API 项目的时候,发现后台接口参数为类型对象,对于PostMan和Ajax的Post方法传Json数据都获取不到相应的值,后来在类型参数前面加了一个[FromBody ...

  3. C#中烦人的Null值判断竟然这样就被消灭了

    作者:依乐祝 首发自:DotNetCore实战 公众号 https://www.cnblogs.com/yilezhu/p/14177595.html Null值检查应该算是开发中最常见且烦人的工作了 ...

  4. ASP.NET Core webapi json 返回时间格式问题

    网站找了几个方案不好使,比如: 1: services.AddMvc().AddJsonOptions(opt => { opt.SerializerSettings.DateFormatStr ...

  5. WebApi——json返回多了 k_BackingField

    产生原因: model类添加了    [System.Serializable] 解决方案: xxxxx.WebApi\App_Start\WebApiConfig.cs的Register函数中添加如 ...

  6. .Net Core 给WebApi接口返回值添加全局的日期格式化

    public void ConfigureServices(IServiceCollection services) { services.AddMvc().AddJsonOptions(option ...

  7. 烦人的Null,你可以走开点了

    1. Null 的问题 假设现在有一个需要三个参数的方法.其中第一个参数是必须的,后两个参数是可有可无的. 第一种情况,在我们调用这个方法的时候,我们只能传入两个参数,对第三个参数,我们在上下文里是没 ...

  8. StackOverflow之旅<1>------{去掉烦人的"!=null"判断}

    问题 为了避免空指针调用,我们经常会看到这样的语句 if (someobject != null) { someobject.doCalc(); } 最终,项目中会存在大量判空代码,多么丑陋繁冗!如何 ...

  9. 去掉烦人的“!=null"(判空语句)

    文章首发于公众号 松花皮蛋的黑板报 作者就职于京东,在稳定性保障.敏捷开发.高级JAVA.微服务架构有深入的理解 为了避免空指针调用,我们经常会看到这样的语句 if (someobject != nu ...

随机推荐

  1. 2、pytorch——Linear模型(最基础版,理解框架,背诵记忆)(调用nn.Modules模块)

    #define y = X @ w import torch from torch import nn #第一模块,数据初始化 n = 100 X = torch.rand(n,2) true_w = ...

  2. 个人作业三——ATM管理系统

    一 作业信息 博客班级 https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/ 作业要求 https://edu.cnblogs.com/campus/a ...

  3. rsync 参数说明及使用参数笔记

    第1章 rsync 命令简介 rsync 是一款开源的.快速的.多功能的.可实现全量及增量的本地或远程数据镜像同步备份的优秀工具. 1.1.1 语法格式 三种模式: 1)本地模式 rsync [选项] ...

  4. 从面试角度分析ArrayList源码

    注:本系列文章中用到的jdk版本均为java8 ArrayList类图如下: ArrayList的底层是由数组实现的,数组的特点是固定大小,而ArrayList实现了动态扩容. ArrayList部分 ...

  5. 在Linux下下载RPM包

    在Linux下下载RPM包,但是不安装 在工作中经常会遇到离线安装RPM包的情况,下面是下载RPM包的方法 # 使用yum下载RPM包 yum -y install --downloadonly &l ...

  6. js处理浏览器兼容

    1.try  catch 在try中执行我们的代码,如果在执行的过程中发生了异常信息,我们在catch中写代替的执行方案 前提:不兼容四位情况下,执行对应的代码,需要发生异常错误才可以检测到 弊端:不 ...

  7. 听说特斯拉花了4个月研发出新ERP,然后很多人都疯了

    欢迎关注微信公众号:sap_gui (ERP咨询顾问之家) 最近这件事儿在SAP圈里炒的挺火的,最主要是因为这几个关键词: 放弃SAP.4个月.自研ERP: 这则新闻一出来,很多人都兴高采烈,都要疯了 ...

  8. 仵航说 SpringBoot项目配置Log日志服务-仵老大

    今天领导让我配置一个log日志服务,我哪里见过哟,然后就去百度了,结果挨个试下去,找到了一个能用的,分享给大家 大致四个地方 分别是 1.pom文件需要引入依赖 2.创建一个TestLog类 3.在y ...

  9. CVE-2019-0708_RDP漏洞利用

    可以说是2019年影响比较大的一个漏洞了, 简述下这个漏洞: Windows系列服务器于2019年5月15号,被爆出高危漏洞,该漏洞影响范围较广如: windows2003.windows2008.w ...

  10. WP | [MRCTF2020]Ezpop

    2020.10.14 最近开始努力提高代码能力 题目代码 Welcome to index.php <?php //flag is in flag.php //WTF IS THIS? //Le ...