.Net WebApi接收引用类型参数且值为null时赋默认值

备忘:Json字符串反序列化时,对于Null值的处理

(新手小白,如有写错或者有更高明的写法,烦请大佬指正,谢谢!)
最近在做开放接口时,遇到一个问题,API的部分字段是非必填的,当字段类型为引用类型,且客户对接该API时,因为字段非必填,就不给这个字段或直接给null值时,WebApi底层自动反序列化后,你所拿到的数据中,不给或给的值为null的字段,会等于null;

null值容易在系统中引发异常,例如直接赋值到实体上,插入数据库,而数据库该字段不允许为null,则会引发报错,因此,在对数据库操作前需要将为null的值转换为空字符串;

例如:
模型类:

public class AddressInputModel
{
        /// <summary>
        /// 收件人姓名
        /// </summary>
        public string BuyerFullName { get; set; }

        /// <summary>
        /// 收件人国家
        /// </summary>
        public string Country { get; set; }

        /// <summary>
        /// 收件地址省/州
        /// </summary>
        public string BuyerState { get; set; }

        /// <summary>
        /// 收件地址城市
        /// </summary>
        public string BuyerCity { get; set; }

        /// <summary>
        /// 街道地址1
        /// </summary>
        public string BuyerStreet1 { get; set; }

        /// <summary>
        /// 街道地址2
        /// </summary>
        public string BuyerStreet2 { get; set; }

        /// <summary>
        /// 地址邮编
        /// </summary>
        public string BuyerZipCode { get; set; }

        /// <summary>
        /// 联系电话
        /// </summary>
        public string BuyerPhone { get; set; }

        /// <summary>
        /// 收件邮箱
        /// </summary>
        public string BuyerEmail { get; set; }
}

控制器层接口:

[HttpPost]
public object Create(AddressInputModel input)
{
     //参数验证代码&Service方法调用
}

客户给的Json为

{
        "BuyerFullName": "Name",
        "Country": "TH",
        "BuyerState": "A",
        "BuyerCity": "B",
        "BuyerStreet1": "C",
        "BuyerZipCode": "2",
        "BuyerPhone": null,
        "BuyerEmail": ""
}

那么,input.BuyerStreet2、input.BuyerPhone应该是等于null的
遇到这种问题,其实解决的方式有很多,最简单的就是一个个做判断,例如:

if(string.IsNullOrWhiteSpace(input.BuyerStreet2))
   input.BuyerStreet2 = string.Empty;

但是像这种写法,会导致代码冗余难看,毫无复用性
因此我也找度娘查询了一下这种情况的解决方案,可能是所想的关键词不对,一直没有查询到,于是上Newtonsoft.Json查看官方文档,地址:https://www.newtonsoft.com/json

平时用Newtonsoft.Json只用了JsonConvert.SerializeObject、JsonConvert.DeserializeObject最简单的方法,了解别的比较少,在文档浏览中,发现Newtonsoft.Json支持自定义配置反序列化,

//如果 .NET 值在序列化时为空,Json.NET 将跳过写入 JSON 属性,如果在反序列化时 JSON 属性为空,则将跳过设置字段/属性
var setting = new JsonSerializerSettings();
setting.NullValueHandling = NullValueHandling.Ignore;

说明地址:https://www.newtonsoft.com/json/help/html/SerializationSettings.htm

于是自己写了一个公共方法用于处理此类业务场景,直接贴代码
1、首先定义模型的基类,用于赋默认值:

    /// <summary>
    /// 实体模型基类,为防止新增字段为null值报错
    /// </summary>
    public abstract class EntityBase
    {
        /// <summary>
        /// 默认时间
        /// </summary>
        private static readonly DateTime DefaultTime = new DateTime(1900, 1, 1);
        
        protected EntityBase()
        {
            var props = GetType().GetProperties();
            foreach (var prop in props)
            {
                if (prop.PropertyType == typeof(string))
                {
                    prop.SetValue(this, string.Empty);
                }
                if (prop.PropertyType == typeof(DateTime))
                {
                    prop.SetValue(this, DefaultTime);
                }
                if (prop.PropertyType == typeof(decimal))
                {
                    prop.SetValue(this, 0M);
                }
            }
        }
    }

2、输入模型类继承基类:

public class AddressInputModel : EntityBase
{
        /// <summary>
        /// 收件人姓名
        /// </summary>
        public string BuyerFullName { get; set; }

        /// <summary>
        /// 收件人国家
        /// </summary>
        public string Country { get; set; }

        /// <summary>
        /// 收件地址省/州
        /// </summary>
        public string BuyerState { get; set; }

        /// <summary>
        /// 收件地址城市
        /// </summary>
        public string BuyerCity { get; set; }

        /// <summary>
        /// 街道地址1
        /// </summary>
        public string BuyerStreet1 { get; set; }

        /// <summary>
        /// 街道地址2
        /// </summary>
        public string BuyerStreet2 { get; set; }

        /// <summary>
        /// 地址邮编
        /// </summary>
        public string BuyerZipCode { get; set; }

        /// <summary>
        /// 联系电话
        /// </summary>
        public string BuyerPhone { get; set; }

        /// <summary>
        /// 收件邮箱
        /// </summary>
        public string BuyerEmail { get; set; }
}

3、定义一个方法用于重新赋值

        /// <summary>
        /// Json反序列化
        /// 默认的Json反序列化会将为null的值赋值到字段
        /// 调用此方法,为null的字段将不会赋值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public T DeserializeNullValueHandling<T>(T model)
        {
            var inputStr = JsonConvert.SerializeObject(model);
            var setting = new JsonSerializerSettings();
            setting.NullValueHandling = NullValueHandling.Ignore;
            model = JsonConvert.DeserializeObject<T>(inputStr, setting);
            return model;
        }

4、方法调用:

[HttpPost]
public object Create(AddressInputModel input)
{
     input = DeserializeNullValueHandling(input);
     .............
}

问题搞定,且方法复用性强,可以省掉很多代码

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值