简体   繁体   English

将JSON字符串反序列化为枚举

[英]Deserialize JSON string into an enum

I'm trying to figure out how to deserialize a JSON string into an enum. 我试图弄清楚如何将JSON字符串反序列化为枚举。 Right now I'm taking a serialized Dictionary, passing it to an HttpPut method, and deserializing that string in order to update fields on a custom object using reflection. 现在,我正在使用序列化的Dictionary,将其传递给HttpPut方法,并反序列化该字符串以使用反射更新自定义对象上的字段。 Here's what I have so far: 这是我到目前为止的内容:

I'm putting values into the Dictionary like this: 我将值放入字典中,如下所示:

  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

I'm using JSON to serialize is like this: 我正在使用JSON进行序列化,如下所示:

string jsonString = JsonConvert.SerializeObject(valuesToUpdate);

I then take the jsonString and send it over to a REST API PUT call. 然后,我将jsonString传送给REST API PUT调用。 My goal with this is to update various variables for a custom object based on the Key values in the dictionary using reflection (in this example I'll be updating customObject.Confidence and customObject.Length). 我的目标是使用反射根据字典中的键值更新自定义对象的各种变量(在本示例中,我将更新customObject.Confidence和customObject.Length)。

The PUT call deserializes the jsonString like this: PUT调用会反序列化jsonString,如下所示:

Dictionary<string, object> newFields = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);

My plan is to iterate through newFields and use reflection to update customObject's fields. 我的计划是遍历newFields并使用反射来更新customObject的字段。 Right now I have some code that works when the dictionary finds strings or doubles but I'm having issues with other types - mainly enums and classes. 现在,当字典找到字符串或双精度型时,我有一些代码可以工作,但是其他类型(主要是枚举和类)存在问题。 So basically, how would one go about taking a serialized json dictionary string, deserialize it into the appropriate type for reflection? 因此,基本上,如何处理序列化的json字典字符串,将其反序列化为适当的类型以进行反射? With the example I've posted, "Length" will update properly, but "Confidence" will throw this error: 在我发布的示例中,“长度”将正确更新,但是“信心”将引发此错误:

Object of type 'System.Int64' cannot be converted to type 'System.Nullable'1.

This is my HttpPut method that reads the jsonString: 这是我的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);
        }
}

So it seems likes it's deserializing the original enum into type Int64. 因此,似乎将原始枚举反序列化为Int64类型。 How would I go about getting it to recognize it as the original type of SimpleConfidence which is an enum? 我将如何将其识别为枚举的原始类型的SimpleConfidence?

The type identity of the enum SimpleConfidence is lost between the serialization and deserialization. 枚举SimpleConfidence的类型标识在序列化和反序列化之间丢失。 You can patch it around by adding some special handling on the assignment part : 您可以通过在分配部分添加一些特殊处理来修补它:

//...

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM