最近在项目中启用了Nullable 可为空的类型,这个特性确实很好用,在 WebAPI 的入参上可以直接采用 ? 来标记一个字段是否允许为空,但是使用过程中遇到了如下一个问题,比如创建部门接口

我们定义入参模型如下:

  1. public class DtoDepartment
  2. {
  3. /// <summary>
  4. /// 部门名称
  5. /// </summary>
  6. public string Name { get; set; }
  7. /// <summary>
  8. /// 上级部门ID
  9. /// </summary>
  10. public Guid? ParentId { get; set; }
  11. }

我们这里将上级部门ID定义为可以为空的类型,因为有些部门不存在上级部门

然后定义这样一个接口

  1. [HttpPost("CreateDepartment")]
  2. public bool CreateDepartment(DtoDepartment department)
  3. {
  4. //省略业务逻辑
  5. return true;
  6. }

当前端请求的时候传入如下Json 时则就会触发异常

  1. {
  2. "name": "商务一部",
  3. "parentId": ""
  4. }

异常内容为:

  1. {
  2. "errMsg": "The department field is required. | The JSON value could not be converted to System.Nullable`1[System.Guid]. Path: $.parentId | LineNumber: 2 | BytePositionInLine: 16."
  3. }

像这样的情况是因为虽然我们定义的 Dto 允许上级部门ID字段为空,但是前端调用的时候 parentId 实际传入的是 "" 空字符串,当空字符串给 Guid? 转换的时候就会产生这样的异常,当遇到这样的情况时,我们可以要求前端调整 JSON 格式如下

  1. {
  2. "name": "商务一部",
  3. "parentId": null
  4. }

前端只要给 parentId 的赋值从 "" 调整为 null 之后我们的接口就可以正常运行了,但是有的时候前端的组件这里取值可能是和一些组件库绑定的,不太方便绑定默认值为 null,很多情况下组件库组件的默认值都是 "" 空字符串的形式,所以经过和前端同事多次沟通之后想着从后端彻底解决这个问题,经过研究之后编写了下面的 NullableConverter 转换器,只要在项目启动的时候注册到 AddJsonOptions 其中即可。

  1. using System.Text.Json;
  2. using System.Text.Json.Serialization;
  3. namespace Common.JsonConverter
  4. {
  5. public class NullableConverter<T> : JsonConverter<T?> where T : struct
  6. {
  7. public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  8. {
  9. if (reader.TokenType == JsonTokenType.String)
  10. {
  11. if (string.IsNullOrEmpty(reader.GetString()) || string.IsNullOrWhiteSpace(reader.GetString()))
  12. {
  13. return null;
  14. }
  15. }
  16. return JsonSerializer.Deserialize<T>(ref reader, options);
  17. }
  18. public override void Write(Utf8JsonWriter writer, T? value, JsonSerializerOptions options)
  19. {
  20. JsonSerializer.Serialize(writer, value!.Value, options);
  21. }
  22. }
  23. }

上面我们只是用 Guid? 举了一个例子,实际情况下

  • DateTime?
  • DateTimeOffset?
  • long?
  • int?
  • double?
  • decimal?
  • float?
  • Guid?
  • bool?

都有可能存在这个问题,所以我们为这几种类型都配置了这个可为空类型转换器。这样前端在调用接口时配到这类型的字段,传 "" 和 null 我们后端就都可以接收了,收到之后字段的值都是 null

我这里项目采用的是微软的 System.Text.Json 处理的 Json 序列化,注册配置 NullableConverter 代码如下:

  1. #region 注册 Json 序列化配置
  2. builder.Services.AddControllers().AddJsonOptions(options =>
  3. {
  4. options.JsonSerializerOptions.Converters.Add(new Common.JsonConverter.NullableConverter<DateTime>());
  5. options.JsonSerializerOptions.Converters.Add(new Common.JsonConverter.NullableConverter<DateTimeOffset>());
  6. options.JsonSerializerOptions.Converters.Add(new Common.JsonConverter.NullableConverter<long>());
  7. options.JsonSerializerOptions.Converters.Add(new Common.JsonConverter.NullableConverter<int>());
  8. options.JsonSerializerOptions.Converters.Add(new Common.JsonConverter.NullableConverter<double>());
  9. options.JsonSerializerOptions.Converters.Add(new Common.JsonConverter.NullableConverter<decimal>());
  10. options.JsonSerializerOptions.Converters.Add(new Common.JsonConverter.NullableConverter<float>());
  11. options.JsonSerializerOptions.Converters.Add(new Common.JsonConverter.NullableConverter<Guid>());
  12. options.JsonSerializerOptions.Converters.Add(new Common.JsonConverter.NullableConverter<bool>());
  13. });
  14. #endregion

至此 .NET WebAPI 自定义 NullableConverter 解决请求入参 “”空字符触发转换异常问题 就讲解完了,有任何不明白的,可以在文章下面评论或者私信我,欢迎大家积极的讨论交流,有兴趣的朋友可以关注我目前在维护的一个 .NET 基础框架项目,项目地址如下

https://github.com/berkerdong/NetEngine.git

https://gitee.com/berkerdong/NetEngine.git

.NET WebAPI 自定义 NullableConverter 解决请求入参 “”空字符触发转换异常问题的更多相关文章

  1. charles请求入参中有乱码

    工作中,需要入参,但是发现入参中,有中文的都是乱码,仔细查阅headers,发现Content-Type是application/x-www-form-urlencoded类型,而实际上,入参是jso ...

  2. Jmeter之发送请求入参必须使用编码格式、Jmeter之发送Delete请求可能入参需要使用编码格式

    这里的其中一个属性值必须要先编码再传参才可以,具体可以通过抓包分析观察:

  3. POST 发送HTTP请求入参为:String url, Map<String, Object> propsMap

    /** * 发送HTTP请求 * * @param url * @param propsMap * 发送的参数 */ public static String httpSend(String url, ...

  4. java获取访问路径、域名、项目名、请求入参

    废话不多说(这句不是废话吗>>),直接提出可以运行的类,你放到一个web项目访问下就知道了. //测试页面-跳转到输入数据的form表单 public String test1(){ Ac ...

  5. Taurus.MVC 2.2 开源发布:WebAPI 功能增强(请求跨域及Json转换)

    背景: 1:有用户反馈了关于跨域请求的问题. 2:有用户反馈了参数获取的问题. 3:JsonHelper的增强. 在综合上面的条件下,有了2.2版本的更新,也因此写了此文. 开源地址: https:/ ...

  6. 解决WebApi入参时多对象的问题

    我们的项目是用WebApi提供数据服务,且WebPage跟APP中都有调用到. WebApi提供的接口一多,就发现一个问题,我们项目中有很多接口是接收POST(安全原因,我们采用的是https)请求的 ...

  7. springMVC中 request请求数据绑定到Controller入参 过程剖析

    前言:Controller方法的参数类型可以是基本类型,也可以是封装后的普通Java类型.若这个普通Java类型没有声明任何注解,则意味着它的每一个属性都需要到Request中去查找对应的请求参数.众 ...

  8. [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参

    [转]ASP.NET MVC学习系列(二)-WebAPI请求 传参 本文转自:http://www.cnblogs.com/babycool/p/3922738.html ASP.NET MVC学习系 ...

  9. spring mvc绑定对象String转Date解决入参不能是Date的问题

    使用spring的mvc,直接将页面参数绑定到对象中,对象中有属性为Date时会报错,此时需要处理下. 同样的,其他的需要处理的类型也可以用这种方法. 在controller中加入代码 @InitBi ...

随机推荐

  1. RS485 MODBUS RTU通信协议

    1.RS485接口标准 RS485由RS232和RS422发展而来,弥补了抗干扰能力差.通信距离短.速率低的缺点,增加了多点.双向通信能力,即允许多个发送器连接在同一条主线上,同时增加了发送器的驱动能 ...

  2. labview从入门到出家8(进阶篇)--简单好用的状态机

    labview的状态机类似于一个软件框架的基本单元,好的软件框架和软件思路采用一个好的状态机,就如虎添翼了.这章给大家讲一个本人常用的一个状态机,基本上以前的项目都是建立在这个状态机上完成的,当然网上 ...

  3. 简记清空C语言输入残留内容

    为了在命令行程序中实现和用户的交互,我们编写的程序的运行过程中往往涉及到对标准输入/输出流的多次读写. 在C语言中接受用户输入这一块,有着一个老生常谈的问题:"怎么样及时清空输入流中的数据? ...

  4. Note -「0/1 Fractional Programming」

    What is that? Let us pay attention to a common problem that we often meet in daily life: There are \ ...

  5. DeiT:注意力也能蒸馏

    DeiT:注意力也能蒸馏 <Training data-efficient image transformers & distillation through attention> ...

  6. gdb调试器在windows下的相关内容

    1.gdb调试器在visual studio或dev c++中也有类似的调试图形化可视界面,但是gdb不同的是它是由命令行组成,他的界面对于习惯图形化可视界面的用户来说一时间会不知所措 2.通过gcc ...

  7. 关于标准IO缓冲区的问题

    关于标准IO缓冲区的问题 按照标准IO缓冲区可以分为三类: 不缓存类型: 一旦有数据,直接将数据写入到文件 行缓冲类型: 同全缓冲类型 遇到\n时,将数据写入文件 全缓冲类型: 当程序结束,将数据冲洗 ...

  8. win10系统下把玩折腾DockerToolBox以及更换国内镜像源(各种神坑)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_149 2020年,这年头如果出去面试和面试官不聊几句Docker,都不好意思说自己是搞开发的.之前玩儿Docker都是在Mac系统 ...

  9. ToString()格式化输出

    C 货币 2.5.ToString("C") ¥2.50 D 十进制数 25.ToString("D5") 00025 E 科学型 25000.ToString ...

  10. react环境搭建及文件配置

    webpack简介 构建工具(基于Nodejs)node(v16)前端工程化. 环境搭建 创建一个空的package.json npm init webpack核心包(提供了API,插件) npm i ...