.NET Core 处理 WebAPI JSON 返回烦人的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 }

深圳网站建设www.sz886.com

推荐阅读 更多精彩内容