JsonConvert反序列化枚举转换
适用场景:反序列化对象里面存在枚举类型
说明
在使用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));
}
}
- 通过重写CanConvert,判断当前转换器是否能处理类型 T,只针对类型T进行转换
- ReadJson是转换的核心,实现将 JSON 字符串或数字安全地转换为枚举类型 T。
- 如果 JSON 是字符串(如 "1" 或 "EnumName"):
先尝试转成数字(如 "1" → 1 → 枚举值)。
再尝试转成枚举名(如 "EnumName" → 枚举值)。
- 如果 JSON 是数字(如 1):
直接转成枚举值。
- 如果都不行,返回默认值(通常是0)。 - WriteJson:结果输出,将枚举值序列化为数字(int),而不是字符串。
使用方法
在需要的枚举属性上加特性,或全局注册:
[JsonConverter(typeof(SafeEnumConverter<MyEnum>))]
public MyEnum Status { get; set; }
或者
JsonConvert.DeserializeObject<T>(json, new SafeEnumConverter<MyEnum>());
能兼容数字、字符串等多种Json输入的转换
JsonConvert反序列化枚举转换的更多相关文章
- mybatis自定义枚举转换类
转载自:http://my.oschina.net/SEyanlei/blog/188919 mybatis提供了EnumTypeHandler和EnumOrdinalTypeHandler完成枚举类 ...
- Mybatis枚举转换
自定义mybatis枚举转换,原理是如果用户没有定义自己的枚举转换工具,mybatis在解析枚举类时会自动获取mybatis的BaseTypeHandler,来转换枚举类,我们只需要重写这个枚举转换器 ...
- (转)C# Enum,Int,String的互相转换 枚举转换
Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...
- C# Enum,Int,String的互相转换 枚举转换
Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...
- spring mvc4的日期/数字格式化、枚举转换
日期.数字格式化显示,是web开发中的常见需求,spring mvc采用XXXFormatter来处理,先看一个最基本的单元测试: package com.cnblogs.yjmyzz.test; i ...
- (转载)C#:Enum、Int和String的互相转换,枚举转换
Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举.注意:枚举类型的基类 ...
- 【转】C# Enum,Int,String的互相转换 枚举转换
Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...
- Enum,Int,String的互相转换 枚举转换
Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...
- (转)C# Enum,Int,String的互相转换 枚举转换--非常实用
Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举. 注意:枚举类型的基 ...
- Jackson反序列化枚举类型解决方案
BUG描述 在使用SpringBoot自带的jackson处理客户端提交的消息体反序列化时,遇到一个非常棘手的情况 客户端发送如下json {"content":"654 ...
随机推荐
- Mysql数据库常用操作和Mysql大数据高效迁移方案
1.数据迁移: 1.数据量较少时可使用mysqldump和mysql命令导出和导入 # 导出指定数据库系统 mysqldump -u _username -p _dbname > _sqlfil ...
- 题解:P10862 [HBCPC2024] Spicy or Grilled?
题目翻译: 有 nnn 个人,我们为他们买了香辣鸡肉汉堡套餐,每份是 aaa 元,可是里面有 xxx 人不能吃辣,于是还准备了 xxx 份烤鸡汉堡套餐,每份是 bbb 元,求总共要多少元. 解题思路 ...
- 数据结构之位图(bitmap、RoaringMap)
参照资料: 1.https://www.bilibili.com/video/BV1u44y1g7Ps(bitmap) 2.https://b23.tv/cQtuFOx (RoaringMap) 3. ...
- SpringBoot错误处理
SpringBoot错误处理 1 SpringMVC写法 1.1 在单独的Controller写一个处理异常的方法处理 @Slf4j @RestController public class Hell ...
- 【译】Visual Studio Hub 介绍
跟上最新的 Visual Studio 更新.特性和资源就像是一项全职工作.我们已经听过一次又一次了--您想要一种更简单的方式来获取信息,而不是在分散的博客文章.发布说明和社交媒体更新中挖掘. 这就是 ...
- HarmonyOS NEXT开发实战案例--抽奖转盘
这是之前写过的一个项目,后来删掉了,现在适配到api12重新发布,友友们按需查阅. 本文主要通过抽奖转盘小项目讲解在鸿蒙开发中如何使用画布组件Canvas绘制图形和文字,以及转圈动画的实现.效果图如下 ...
- vue3 基础-slot 插槽
前几篇的内容都是父子组件通过属性传值或者事件传值这样的. 本篇来学习父组件在调用子组件时, 如果想要给子组件传递特定的内容 (dom) , 则可通过 slot 这个设计来轻易实现哦. 例如现在有这样一 ...
- 如何清理误提交到git的历史大文件?
前言 哈喽!好久不见~ 最近在思考转型的事情,好久没有更新文章了 不过看到我之前开发的视频剪辑工具 Clipify 收获了不少 star ,让我想起之前画的饼似乎才实现了一点点,所以利用了周末的空闲时 ...
- Spring 注解之@Primary注解
当一个接口有多个不同实现类时,使用注解@Autowired时会报 org.springframework.beans.factory.NoUniqueBeanDefinitionException ...
- AtCoder Beginner Contest 381-E
AtCoder Beginner Contest 381-E Problem 一个长度为奇数.最中间的那个字符是 /.左边所有字符都是都是 1.右边所有字符都是 2 的字符串被称为11/22 字符串. ...