【问题标题】:Deserialize JSON string into an enum将 JSON 字符串反序列化为枚举
【发布时间】:2016-04-18 20:09:53
【问题描述】:

我试图弄清楚如何将 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);

然后我获取 jsonString 并将其发送到 REST API PUT 调用。我的目标是使用反射根据字典中的键值更新自定义对象的各种变量(在本例中,我将更新 customObject.Confidence 和 customObject.Length)。

PUT 调用像这样反序列化 jsonString:

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.

这是我读取 jsonString 的 HttpPut 方法:

[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 的原始类型,即枚举?

【问题讨论】:

    标签: c# json enums deserialization http-put


    【解决方案1】:

    枚举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);
        }
    
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 2011-01-08
    • 2012-02-27
    • 2021-06-10
    • 2019-02-28
    • 1970-01-01
    相关资源
    最近更新 更多