如果一个属性可以有不同的类型,如何序列化DataContract的成员?

时间:2014-06-11 23:56:35

标签: c# json xaml windows-phone-8

我有以下json(由API提供):

[
    {
        "type": "text",
        "values": [
            {
                "value": "Text that is in textfield"
            }
        ]
    },
    {
        "type": "category",
        "values": [
            {
                "value": {
                    "text": "Category title",
                    "color": "#000000"
                }
            }
        ]
    }
]

当values.value是动态的时,你如何将这样的对象呈现为强类型(C#需要你)?

以下是有关我的问题的更多信息: Trying to map two different types to one value

但我想保留这个新问题。


抱歉碰撞,但我仍然无法让这个工作!有关如何序列化这个的任何例子吗?

我目前有这个代码序列化:

[DataContract]
public class MyField
{
    [DataMember]
    public List<MyValue> values { get; set; }
}

[DataContract]
public class MyValue
{
    [DataMember]
    public object value { get; set; } // This will crash because it needs to be both a string and an object with text,color properties??
}

using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(response)))
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<MyField>));
    return (List<MyField>)serializer.ReadObject(stream);
}

但它在values.value位崩溃,因为它无法转换为强类型...因为它是变化的。

//// ////编辑

Sureeeely有人在此之前完成了这个!!!

2 个答案:

答案 0 :(得分:1)

基本上你会想要将Value定义为Dictionary,因为它是动态的。

至于如何序列化它,取决于您使用的是哪个序列化程序。我个人更喜欢Newtonsoft的JSON.NET。你可以在SO上找到很多关于如何将字典序列化为JSON的例子。

以下是使用datacontractjsonserializer的内容:Deserialize JSON to Dictionary with DataContractJsonSerializer

以下是使用json.net的示例:How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?

<强>更新

以下是使用JSON.NET对数组中的混合类型进行反序列化的方法,并且仍然保持强类型。关键是JSONConverter实现,它基本上指示序列化程序反序列化为字符串或类型(属性)。

public static void Main()
{
    using (FileStream stream = File.OpenRead("TextFile1.txt"))
    using (StreamReader reader = new StreamReader(stream))
    {
        JsonSerializer ser = new JsonSerializer();
        List<MyField> result = ser.Deserialize<List<MyField>>(new JsonTextReader(reader));
    }       
}





public class MyField
{
    public string type { get; set; }        
    public List<MyValue> values { get; set; }
}


public class MyValue
{
    [JsonConverter(typeof(MyConverter))]
    public object value { get; set; }
}

public class MyAttributes
{
    public string text { get; set; }
    public string color { get; set; }
}


public class MyConverter : JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.String)
        {
            return serializer.Deserialize<string>(reader);
        }
        else
        {
            return serializer.Deserialize<MyAttributes>(reader);
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

答案 1 :(得分:0)

DataContractJsonSerializer在这里没用......

我终于使用了Json.Net ......

然后只需将你的字符串传递给解析(确保它不是一个数组,而是一个包含你的数组的对象)...你可以看到我是如何加上后缀并用pubes作为我的回应的前缀:

JObject jObject = JObject.Parse("{\"data\": " + response + "}");
JToken jData = jObject["data"];

然后你可以随心所欲:

string type = (string)jData["type"];

并且当然这意味着我现在可以对类型进行切换,然后创建任何所需类型的对象。