使用Json进行枚举反序列化.Net:将值转换为类型错误
本文关键字:转换 错误 类型 Net Json 枚举 反序列化 使用 | 更新日期: 2023-09-27 18:05:07
我使用Json。. NET来序列化/反序列化一些JSON api。
API响应具有一些整数值,这些整数值映射到应用程序中定义的Enum。
枚举如下:
public enum MyEnum
{
Type1,
Type2,
Type3
}
和JSON API响应有以下内容:
{
"Name": "abc",
"MyEnumValue":"Type1"
}
有时API会返回MyEnumValue字段的值,而这个值没有在我的enum中定义,就像这样:
{
"Name": "abc",
"MyEnumValue":"Type4"
}
抛出异常:
转换值"type4"错误;输入'MyEnum'
是否有一种方法来处理这个错误,通过分配一个默认值或其他东西,以避免应用程序崩溃?
在我看来,您应该编写自己的转换器。但是在StringEnumConverter
课上已经完成了一半的工作。我们只能重写ReadJson
方法
class Program
{
static void Main(string[] args)
{
const string json = @"{
'Name': 'abc',
'Type':'Type4'
}";
// uncomment this if you want to use default value other then default enum first value
//var settings = new JsonSerializerSettings();
//settings.Converters.Add(new FooTypeEnumConverter { DefaultValue = FooType.Type3 });
//var x = JsonConvert.DeserializeObject<Foo>(json, settings);
var x = JsonConvert.DeserializeObject<Foo>(json);
}
}
public class Foo
{
public string Name { get; set; }
public FooType Type { get; set; }
}
public enum FooType
{
Type1,
Type2,
Type3
}
public class FooTypeEnumConverter : StringEnumConverter
{
public FooType DefaultValue { get; set; }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
try
{
return base.ReadJson(reader, objectType, existingValue, serializer);
}
catch (JsonSerializationException)
{
return DefaultValue;
}
}
}
假设我们有以下json字符串:
[
{
"Name": "abc",
"MyEnumValue": "Type1"
},
{
"Name": "abcd",
"MyEnumValue": "Type2"
},
{
"Name": "abcde",
"MyEnumValue": "Type3"
} ,
{
"Name": "abcdef",
"MyEnumValue": "Type4"
}
]
和下面的类和enum:
public class MyClass
{
public string Name { get; set; }
public MyEnum MyEnumValue { get; set; }
}
public enum MyEnum
{
Type1,
Type2,
Type3
}
可以注意到,json字符串数组中包含不能正确映射到MyEnum
的项目(最后一个)。要避免反序列化错误,可以使用以下代码片段:
static void Main(string[] args)
{
var serializationSettings = new JsonSerializerSettings
{
Error = HandleDeserializationError
};
var lst = JsonConvert.DeserializeObject<List<MyClass>>(jsonStr, serializationSettings);
}
public static void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
{
errorArgs.ErrorContext.Handled = true;
var currentObj = errorArgs.CurrentObject as MyClass;
if (currentObj == null) return;
currentObj.MyEnumValue = MyEnum.Type2;
}
,其中jsonStr
变量是上面发布的json字符串。在上面的代码示例中,如果不能正确解释MyEnumValue
,则将其设置为默认值Type2
。
示例:https://dotnetfiddle.net/WKd2Lt
如果您不想创建自定义转换器,则可以选择将其映射到DTO中的私有字符串字段,然后使用Enum。在该字段的属性getter中尝试解析:
public class MyClass
{
[JsonProperty("MyEnumValue")]
private string myEnumValue;
public string Name { get; set; }
[JsonIgnore]
public MyEnum MyEnumValue
{
get
{
MyEnum outputValue = MyEnum.Default;
Enum.TryParse(myEnumValue, out outputValue);
return outputValue;
}
}
}