问题
在我们日常开发中,都会遇到有些json数据返回是null,这是因为我们数据库是允许存null值的关系
默认json例子:
{
"code": 0,
"msg": "获取成功",
"data": {
"id": "e90f79fa39ae488f8e2388416b534aeb",
"approvalStatus": 3,
"createTime": "2021-10-13",
"hospitalId": "030d21d44f2146a7a0be6637296b9d36",
"leaveDay": null,
"leaveHour": 5,
"leaveReason": "测试5小时请假",
"leaveTypeId": "0518545c8b45458ab38e1b283e00eda5",
"leaveTypeName": "事假",
"modifyUser": null
}
}
字段说明:
字段名 | 字段类型 | 注释 |
---|---|---|
leaveDay | int? | 请假天数 |
modifyUser | string | 修改人 |
解决
最直接的方法就是我们把每个类都写一下默认返回值,假如现有项目一共有100多个实体类,明显工作量也是有一点的。所以我们直接想办法全局配置能修改全部的字段,能偷懒就偷懒。。
1、继承DefaultContractResolver并重写
新增一个继承DefaultContractResolver自定义类NullOutputHandResolver
特别说明:
- 继承DefaultContractResolver则不会改变key的大小写
- 继承CamelCasePropertyNamesContractResolver则key会变成驼峰样式
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace DX.StdTrainning.WebApi
{
/// <summary>
/// null输出处理解析器
/// </summary>
public class NullOutputHandResolver : DefaultContractResolver
{
/// <summary>
/// 创建属性
/// </summary>
/// <param name="type">类型</param>
/// <param name="memberSerialization">序列化成员</param>
/// <returns></returns>
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
return type.GetProperties().Select(c =>
{
var jsonProperty = base.CreateProperty(c, memberSerialization);
jsonProperty.ValueProvider = new NullOutputHandValueProvider(c);
return jsonProperty;
}).ToList();
}
}
public class NullOutputHandValueProvider : IValueProvider
{
private readonly PropertyInfo _memberInfo;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="memberInfo"></param>
public NullOutputHandValueProvider(PropertyInfo memberInfo)
{
_memberInfo = memberInfo;
}
/// <summary>
/// 获取Value
/// </summary>
/// <param name="target"></param>
/// <returns></returns>
public object GetValue(object target)
{
var result = _memberInfo.GetValue(target);
//string
if (_memberInfo.PropertyType == typeof(string) && result == null)
{
result = string.Empty;
}
//int或int?
if ((_memberInfo.PropertyType == typeof(int)||_memberInfo.PropertyType == typeof(int?)) && result == null)
{
result = 0;
}
//long或long?
if ((_memberInfo.PropertyType == typeof(long)|| _memberInfo.PropertyType == typeof(long?)) && result == null)
{
result = 0L;
}
return result;
}
/// <summary>
/// 设置Value
/// </summary>
/// <param name="target"></param>
/// <param name="value"></param>
public void SetValue(object target, object value)
{
_memberInfo.SetValue(target, value);
}
}
}
2、修改Startup.cs的NewtonsoftJson配置
在AddNewtonsoftJson中新增一个配置项ContractResolver
services.AddControllers(options =>
{
})
//全局配置Json序列化处理
.AddNewtonsoftJson(options =>
{
//设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd";
//自定义返回值处理
options.SerializerSettings.ContractResolver = new NullOutputHandResolver();
});
修改后的接口返回json:
{
"code": 0,
"msg": "获取成功",
"data": {
"id": "e90f79fa39ae488f8e2388416b534aeb",
"approvalStatus": 3,
"createTime": "2021-10-13",
"hospitalId": "030d21d44f2146a7a0be6637296b9d36",
"leaveDay": 0,
"leaveHour": 5,
"leaveReason": "测试5小时请假",
"leaveTypeId": "0518545c8b45458ab38e1b283e00eda5",
"leaveTypeName": "事假",
"modifyUser": ""
}
}