适用场景:反序列化对象里面存在枚举类型

说明

在使用JsonConvert.DeserializeObject转换对象的时候,想要更直观的看到值对应的含义,一般会设定一个枚举值,但是在转换的时候,由于传入值的不确定,会无法识别枚举具体类型而报错,需要我们手动拓展

实现

实现方式主要是通过继承JsonConverter,在转换的过程中添加对输入值,以及输出对象的格式进行校验,确保能安全准确的处理枚举类型

核心代码:

    public class SafeEnumConverter<T> : JsonConverter where T : struct
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(T);
} public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
{
var enumText = reader.Value.ToString();
if (string.IsNullOrEmpty(enumText))
return default(T); // 先尝试数字
int intValue;
if (int.TryParse(enumText, out intValue))
return (T)Enum.ToObject(typeof(T), intValue); // 再尝试枚举名
T value;
if (Enum.TryParse<T>(enumText, true, out value))
return value;
}
else if (reader.TokenType == JsonToken.Integer)
{
return (T)Enum.ToObject(typeof(T), Convert.ToInt32(reader.Value));
}
return default(T);
} public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(Convert.ToInt32(value));
}
}
  1. 通过重写CanConvert,判断当前转换器是否能处理类型 T,只针对类型T进行转换
  2. ReadJson是转换的核心,实现将 JSON 字符串或数字安全地转换为枚举类型 T。

    - 如果 JSON 是字符串(如 "1" 或 "EnumName"):

    先尝试转成数字(如 "1" → 1 → 枚举值)。

    再尝试转成枚举名(如 "EnumName" → 枚举值)。

    - 如果 JSON 是数字(如 1):

    直接转成枚举值。

    - 如果都不行,返回默认值(通常是0)。
  3. WriteJson:结果输出,将枚举值序列化为数字(int),而不是字符串。

使用方法

在需要的枚举属性上加特性,或全局注册:

[JsonConverter(typeof(SafeEnumConverter<MyEnum>))]
public MyEnum Status { get; set; }

或者

JsonConvert.DeserializeObject<T>(json, new SafeEnumConverter<MyEnum>());

能兼容数字、字符串等多种Json输入的转换

JsonConvert反序列化枚举转换的更多相关文章

  1. mybatis自定义枚举转换类

    转载自:http://my.oschina.net/SEyanlei/blog/188919 mybatis提供了EnumTypeHandler和EnumOrdinalTypeHandler完成枚举类 ...

  2. Mybatis枚举转换

    自定义mybatis枚举转换,原理是如果用户没有定义自己的枚举转换工具,mybatis在解析枚举类时会自动获取mybatis的BaseTypeHandler,来转换枚举类,我们只需要重写这个枚举转换器 ...

  3. (转)C# Enum,Int,String的互相转换 枚举转换

    Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...

  4. C# Enum,Int,String的互相转换 枚举转换

    Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...

  5. spring mvc4的日期/数字格式化、枚举转换

    日期.数字格式化显示,是web开发中的常见需求,spring mvc采用XXXFormatter来处理,先看一个最基本的单元测试: package com.cnblogs.yjmyzz.test; i ...

  6. (转载)C#:Enum、Int和String的互相转换,枚举转换

    Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举.注意:枚举类型的基类 ...

  7. 【转】C# Enum,Int,String的互相转换 枚举转换

    Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...

  8. Enum,Int,String的互相转换 枚举转换

    Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...

  9. (转)C# Enum,Int,String的互相转换 枚举转换--非常实用

    Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...

  10. Jackson反序列化枚举类型解决方案

    BUG描述 在使用SpringBoot自带的jackson处理客户端提交的消息体反序列化时,遇到一个非常棘手的情况 客户端发送如下json {"content":"654 ...

随机推荐

  1. fiddler的自动响应器

    1.点击autoresponder,勾选enable rules和unmatched requests passthrough 2.替换步骤 (1)把要替换的会话拉取到空白处,或者选中要替换的内容点击 ...

  2. AD 侦查-MSRPC

    本文通过 Google 翻译 AD Recon – MSRPC (135/539) 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充. 导航 0 前言 1 MSRPC(远 ...

  3. 【经验】Git仓库多账号管理与部署|SSH密钥设置

    生成 SSH 密钥 先打开一个git窗口,生成ssh密钥. 如果打开的不是git窗口,而是cmd窗口,则需要先切换到C:\Users\用户名\.ssh目录下. 下面这条指令的your_email和yo ...

  4. 【工具】没有人能拒绝这三种PDF阅读方式!打造良好的夜间PDF阅读环境,解放你的双眼!White is too harsh!

    方式一和二都适用于常规的浏览器, 方式三是最最好用的PDF阅读器推荐. 方式一:f12改css 步骤一:打开开发者工具(f12). 步骤二:点击选择PDF所在元素,在style里面加一行filter: ...

  5. 【MOOC】华中科技大学操作系统慕课答案-单元作业+第1~2章开放性思考题

    单元作业答案如果没大问题的话,多半是直接摘抄自PPT. 文章目录 第一章 操作系统概述 单元作业(1) 开放性思考题 第二章 操作系统逻辑结构 单元作业 开放性思考题 第三章 操作系统用户界面 单元作 ...

  6. Python基础 - 多进程(下)

    上篇主要对多任务从生活上来认识, 同时引入对 进程 的认识, 即操作系统资源分配的基本单元. 然后通过对 并发, 并行 概念的认识, 去理解 任务调度. 然后用内置的 multiprocessing ...

  7. C#开发的Panel滚动分页控件 - 开源研究系列文章

    前些时候因为想拥有一个自己的软件快捷打开软件,于是参考Windows 11的开始菜单,进行了编写这个应用软件,里面有一个功能就是对显示的Panel里的应用对象的分页功能,于是就想写一个对Panel的自 ...

  8. footer固定在页面底部的几种方法(转载)

    几种非常不错的方法,收藏学习:原文见https://blog.csdn.net/m0_37070714/article/details/77587753 方法一:footer高度固定+绝对定位 < ...

  9. openjdk8下载地址(附赠)

    openjdk下载地址:https://jdk.java.net/ (文末已经为大家下好了,放在网盘里) 进去后点8,win. 安装好后,使用java -version命令如下: 成功安装openjd ...

  10. AI写程序: 多线程网络扫描网段ip工具

    IP Scanner - 多线程网络扫描工具 项目简介 IP Scanner 是一个基于 Python 开发的网络扫描工具,它能够快速扫描指定网段内的活动 IP 地址.该工具采用多线程技术提高扫描效率 ...