将 JSON 字符串反序列化为枚举
Deserialize JSON string into an enum
我正在尝试弄清楚如何将 JSON 字符串反序列化为枚举。现在我正在使用一个序列化的字典,将它传递给一个 HttpPut 方法,然后反序列化该字符串,以便使用反射更新自定义对象上的字段。这是我目前所拥有的:
我正在像这样将值放入字典中:
Dictionary<string, object> valuesToUpdate = new Dictionary<string, object>();
valuesToUpdate.Add("Length", 64.0); //Length is a double
valuesToUpdate.Add("Confidence", SimpleConfidence.THREE); //Confidence is an enum
我使用JSON序列化是这样的:
string jsonString = JsonConvert.SerializeObject(valuesToUpdate);
然后我将 json 字符串发送到 REST API PUT 调用。我的目标是使用反射根据字典中的键值更新自定义对象的各种变量(在本例中,我将更新 customObject.Confidence 和 customObject.Length)。
PUT 调用反序列化 json 字符串,如下所示:
Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
我的计划是遍历 newFields 并使用反射来更新 customObject 的字段。现在我有一些代码可以在字典找到字符串或双精度值时使用,但我遇到了其他类型的问题——主要是枚举和 类。所以基本上,如何将序列化的 json 字典字符串反序列化为适当的类型以进行反射?对于我发布的示例,"Length" 将正确更新,但 "Confidence" 将抛出此错误:
Object of type 'System.Int64' cannot be converted to type 'System.Nullable'1.
这是我的 HttpPut 方法,它读取 jsonString:
[HttpPut("/test/stuff")]
public string PutContact([FromBody]dynamic jsonString)
{
Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
foreach(var field in newFields)
{
Console.WriteLine("\nField key: " + field.Key);
Console.WriteLine("Field value: " + field.Value + "\n");
PropertyInfo propInfo = typeof(CustomObject).GetProperty(field.Key);
var value = propInfo.GetValue(customObject, null);
propInfo.SetValue(customObject, field.Value, null);
}
}
所以它似乎正在将原始枚举反序列化为 Int64 类型。我将如何让它识别为 SimpleConfidence 的原始类型,它是一个枚举?
枚举的类型标识 SimpleConfidence
在序列化和反序列化之间丢失。您可以通过在分配部分添加一些特殊处理来修补它:
//...
foreach(var field in newFields)
{
// ...
PropertyInfo propInfo = typeof(CustomObject).GetProperty(field.Key);
var value = propInfo.GetValue(customObject, null);
PropertyInfo propInfo = null;
// handles TEnum
if (propInfo.PropertyType.IsEnum)
{
propInfo.SetValue(customObject, Enum.ToObject(propInfo.PropertyType, field.Value), null);
}
// handles TEnum?
else if (Nullable.GetUnderlyingType(propInfo.PropertyType)?.IsEnum == true)
// if previous line dont compile, use the next 2
//else if (Nullable.GetUnderlyingType(propInfo.PropertyType) != null &&
// Nullable.GetUnderlyingType(propInfo.PropertyType).IsEnum)
{
propInfo.SetValue(customObject, Enum.ToObject(Nullable.GetUnderlyingType(propInfo.PropertyType), field.Value), null);
}
else
{
propInfo.SetValue(customObject, field.Value, null);
}
}
我正在尝试弄清楚如何将 JSON 字符串反序列化为枚举。现在我正在使用一个序列化的字典,将它传递给一个 HttpPut 方法,然后反序列化该字符串,以便使用反射更新自定义对象上的字段。这是我目前所拥有的:
我正在像这样将值放入字典中:
Dictionary<string, object> valuesToUpdate = new Dictionary<string, object>();
valuesToUpdate.Add("Length", 64.0); //Length is a double
valuesToUpdate.Add("Confidence", SimpleConfidence.THREE); //Confidence is an enum
我使用JSON序列化是这样的:
string jsonString = JsonConvert.SerializeObject(valuesToUpdate);
然后我将 json 字符串发送到 REST API PUT 调用。我的目标是使用反射根据字典中的键值更新自定义对象的各种变量(在本例中,我将更新 customObject.Confidence 和 customObject.Length)。
PUT 调用反序列化 json 字符串,如下所示:
Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
我的计划是遍历 newFields 并使用反射来更新 customObject 的字段。现在我有一些代码可以在字典找到字符串或双精度值时使用,但我遇到了其他类型的问题——主要是枚举和 类。所以基本上,如何将序列化的 json 字典字符串反序列化为适当的类型以进行反射?对于我发布的示例,"Length" 将正确更新,但 "Confidence" 将抛出此错误:
Object of type 'System.Int64' cannot be converted to type 'System.Nullable'1.
这是我的 HttpPut 方法,它读取 jsonString:
[HttpPut("/test/stuff")]
public string PutContact([FromBody]dynamic jsonString)
{
Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
foreach(var field in newFields)
{
Console.WriteLine("\nField key: " + field.Key);
Console.WriteLine("Field value: " + field.Value + "\n");
PropertyInfo propInfo = typeof(CustomObject).GetProperty(field.Key);
var value = propInfo.GetValue(customObject, null);
propInfo.SetValue(customObject, field.Value, null);
}
}
所以它似乎正在将原始枚举反序列化为 Int64 类型。我将如何让它识别为 SimpleConfidence 的原始类型,它是一个枚举?
枚举的类型标识 SimpleConfidence
在序列化和反序列化之间丢失。您可以通过在分配部分添加一些特殊处理来修补它:
//...
foreach(var field in newFields)
{
// ...
PropertyInfo propInfo = typeof(CustomObject).GetProperty(field.Key);
var value = propInfo.GetValue(customObject, null);
PropertyInfo propInfo = null;
// handles TEnum
if (propInfo.PropertyType.IsEnum)
{
propInfo.SetValue(customObject, Enum.ToObject(propInfo.PropertyType, field.Value), null);
}
// handles TEnum?
else if (Nullable.GetUnderlyingType(propInfo.PropertyType)?.IsEnum == true)
// if previous line dont compile, use the next 2
//else if (Nullable.GetUnderlyingType(propInfo.PropertyType) != null &&
// Nullable.GetUnderlyingType(propInfo.PropertyType).IsEnum)
{
propInfo.SetValue(customObject, Enum.ToObject(Nullable.GetUnderlyingType(propInfo.PropertyType), field.Value), null);
}
else
{
propInfo.SetValue(customObject, field.Value, null);
}
}