DataContractJsonSerializer为不同类型的成员抛出InvalidCastException

时间:2010-12-30 02:26:13

标签: c# json deserialization

我想用DataContractJsonSerializer反序列化一段字符串。 JSON字符串中有一个成员,有时可能是对象,有时可能是字符串。像这样:

{ a: 1, b: 2, c: "c" }

{ a: 1, b: 2, c: {c1: 3, c2: 4} }

我知道第二种情况下对象的结构(让我们称之为类Inner),但DataContractJsonSerializer如何转换两种可能类型的对象?

我尝试制作一个显式和隐式的强制转换操作符,以便从string转换为Inner,但它没有被击中。 InvalidCastException不断被抛出。

1 个答案:

答案 0 :(得分:0)

我有类似的情况,其中API返回一个对象数组,或者只返回一个不在数组中的单个对象(如果只有一个结果)。我完全无法让DataContractJsonSerializer这样做。我最终不得不切换到JSON.NET库并使用JsonConverters来使其工作。

在DataContract中,将'c'声明为内部类型。

[DataMember(Name = "c")]
public Inner C { get; set; }

然后编写一个JsonConverter来检查令牌类型,并在反序列化器尝试反序列化内部时执行正确的操作。

internal class StringOrInnerConverter : JsonConverter {
    public override bool CanConvert(Type objectType) {
        return objectType == typeof(Inner);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        var ser = new JsonSerializer();

        if (reader.TokenType == JsonToken.StartObject) {
            var inn = ser.Deserialize<Inner>(reader);
            return inn;
        } else if (reader.TokenType == JsonToken.String) {
            var str = ser.Deserialize<string>(reader);
            return (Inner)str; // Or however you want to convert string to Inner
        } else {
            return default(Inner);
        }
    }

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