使用System.Text.Json序列化反序列化object属性时遇无效转换异常
解决System.Text.Json反序列化Object属性时的JsonElement转换错误
当你用System.Text.Json反序列化带有Object类型的属性时,默认会将该属性反序列化为JsonElement而非实际的.NET基本类型(如String、Boolean),这就是你遇到InvalidCastException的原因。以下是两种可行的解决方法:
方法一:自定义Object类型转换器(推荐)
通过自定义JsonConverter,让System.Text.Json自动将JSON值转换为对应的.NET基本类型,无需手动处理JsonElement。
- 创建自定义转换器类:
Public Class ObjectConverter Inherits JsonConverter(Of Object) Public Overrides Function Read(ByVal reader As Utf8JsonReader, ByVal typeToConvert As Type, ByVal options As JsonSerializerOptions) As Object Return reader.TokenType Switch JsonTokenType.String => reader.GetString(), JsonTokenType.Number => If(reader.TryGetInt64(out Dim longValue), longValue, reader.GetDouble()), JsonTokenType.True => True, JsonTokenType.False => False, JsonTokenType.Null => Nothing, ' 若需要处理数组或复杂对象,可在此扩展逻辑 Else => JsonDocument.ParseValue(ref reader).RootElement.Clone() End Switch End Function Public Overrides Sub Write(ByVal writer As Utf8JsonWriter, ByVal value As Object, ByVal options As JsonSerializerOptions) JsonSerializer.Serialize(writer, value, value.GetType(), options) End Sub End Class
- 在序列化配置中添加该转换器:
修改你的GetJsonSerializerOptions方法,将自定义转换器加入配置:
Private Function GetJsonSerializerOptions() As JsonSerializerOptions Return New JsonSerializerOptions() With { .PropertyNamingPolicy = Nothing, .WriteIndented = True, .AllowTrailingCommas = True, .DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, .Converters = {New ObjectConverter()} } End Function
这样配置后,Answer属性在反序列化时会自动转换为对应的.NET类型(字符串、布尔值、数字等),直接使用即可。
方法二:手动处理JsonElement类型转换
如果不想修改全局序列化配置,可以在使用Answer属性时,先判断类型并手动转换:
If TypeOf Answer Is JsonElement Then Dim jsonElement = DirectCast(Answer, JsonElement) Select Case jsonElement.ValueKind Case JsonValueKind.String Dim strAnswer = jsonElement.GetString() ' 处理字符串类型的Answer Case JsonValueKind.True, JsonValueKind.False Dim boolAnswer = jsonElement.GetBoolean() ' 处理布尔类型的Answer Case JsonValueKind.Number If jsonElement.TryGetInt64(out Dim intAnswer) Then ' 处理整数类型 Else Dim doubleAnswer = jsonElement.GetDouble() ' 处理浮点数类型 End If Case JsonValueKind.Null ' 处理空值 End Select Else ' 此时Answer已经是实际的.NET类型,直接使用 Dim actualValue = Answer End If
注意事项
- 如果
Answer属性需要存储复杂自定义对象,方法一中的转换器需要扩展处理逻辑,将JsonElement反序列化为对应的自定义类型。 - 方法一的全局配置会影响所有
Object类型属性的序列化/反序列化行为,适合全局统一处理的场景;方法二更灵活,适合局部处理特定属性的场景。
内容的提问来源于stack exchange,提问作者Willy
相关产品推荐
相关产品推荐

