使用未知值类型反序列化JSON

时间:2015-01-23 23:10:54

标签: c# json json.net

使用C#,特别是JSON.net如何处理可以具有动态值的JSON对象。例如:

{     “MESSAGE_ID”: “123-456”,     “数据”:[ “数据”, “列表”],     “类型”: “MSG_TYPE1” }

{     “MESSAGE_ID”: “123-457”,     “data”:“我的数据字符串”,     “类型”: “MSG_TYPE2” }

{     “MESSAGE_ID”: “123-458”,     “数据”:{ “KEY1”: “VALUE1”, “KEY2”: “VALUE2”},     “类型”: “MSG_TYPE3” }

“数据”值可以是任何类型。在C#中,我定义了一个包含这些属性的ServiceMessage类,但是“data”应该是什么类型的属性。我正在寻找一个JToken或JContainer,但我不确定最好的实施方式。

public class ServiceMessage
{
    public string message_id { get; set; }
    public JContainer data { get; set; }
    public string type { get; set; }

    public string getJSON()
    {
        string json = JsonConvert.SerializeObject(this);
        return json;
    }

    public void setJSON(string json)
    {
            dynamic jsonObj = JsonConvert.DeserializeObject(json);

            this.message_id = jsonObj.message_id;
            this.type = jsonObj.type;
            this.data = // what goes here.
    }
}

2 个答案:

答案 0 :(得分:0)

你在做什么数据?将它保留为json字符串并在需要数据时处理它是有意义的。

答案 1 :(得分:0)

嗯,我不确定这是否合适,但这就是我想出来的。 我从here

大量借用
class ServiceMessageConverter : CustomCreationConverter<ServiceMessage>
{

    public override ServiceMessage Create(Type objectType)
    {
        return new ServiceMessage();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var msg = new ServiceMessage();
        string data_string = "";

        //get an array of the object's props so I can check if the JSON prop s/b mapped to it
        var objProps = objectType.GetProperties().Select(p => p.Name.ToLower()).ToArray();

        while (reader.Read())
        {
            if (reader.Value == null)
            {
                continue;
            }
            // read the property name
            string readerValue = reader.Value.ToString().ToLower();

            // read the property value
            if (reader.Read())
            {
                // make sure the complex types are saved as strings
                if (readerValue.ToLower() == "data")
                {
                    if (reader.TokenType == JsonToken.StartObject)
                    {
                        dynamic data_obj = serializer.Deserialize(reader);
                        data_string = data_obj.ToString();
                    }
                    else if (reader.TokenType == JsonToken.StartArray)
                    {
                        dynamic data_obj = serializer.Deserialize(reader);
                        data_string = data_obj.ToString();
                    }
                    else
                    {
                        data_string = reader.Value.ToString();
                    }
                    // stuff the data element value into the ServiceMessage
                    PropertyInfo pi = msg.GetType().
                        GetProperty("data", BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                    pi.SetValue(msg, data_string);
                }
                else
                {
                    // stuff the value into the ServiceMessage
                    PropertyInfo pi = msg.GetType().
                        GetProperty(readerValue, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
                    var convertedValue = Convert.ChangeType(reader.Value, pi.PropertyType);
                    pi.SetValue(msg, convertedValue, null);
                }

            }
        }
        return msg;

    }
}