在正常情况下,您可以将data 属性定义为List<Dictionary<string, string>>,如下所示:
[DataMember(Name = "data", IsRequired = true)]
public List<Dictionary<string, string>> data { get; set; }
然后您将能够使用 Json.NET 成功对其进行序列化和反序列化。不幸的是,您的一个数据对象有重复键:
{
"groupId":"group1",
"failbackAction":"null",
"normal":"null",
"failoverAction":"null",
"failbackAction":"null",
"failoverAction":"null",
"artifactId":"mywebserver",
"normalState":"null"
},
JSON standard 不建议使用重复的密钥,其中指出:
当对象中的名称不唯一时,接收此类对象的软件的行为是不可预测的。
另外,c#字典当然不支持重复键,数据契约序列化也不支持重复属性名。
但是,可以使用 Json.NET 的 JsonReader 读取具有重复键的 JSON 对象,并创建一个 custom JsonConverter 来处理重复键。
首先,定义以下类来替换JsonValue。 JsonValue 是一个特定于 Silverlight 的类,它的使用一直是 deprecated in overall .Net:
[JsonConverter(typeof(JsonValueListConverter))]
public sealed class JsonValueList
{
public JsonValueList()
{
this.Values = new List<KeyValuePair<string, string>>();
}
public List<KeyValuePair<string, string>> Values { get; private set; }
}
class JsonValueListConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(JsonValueList).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var jsonValue = (existingValue as JsonValueList ?? new JsonValueList());
if (reader.TokenType != JsonToken.StartObject)
throw new JsonSerializationException("Invalid reader.TokenType " + reader.TokenType);
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.Comment:
break;
case JsonToken.PropertyName:
{
var key = reader.Value.ToString();
if (!reader.Read())
throw new JsonSerializationException(string.Format("Missing value at path: {0}", reader.Path));
var value = serializer.Deserialize<string>(reader);
jsonValue.Values.Add(new KeyValuePair<string, string>(key, value));
}
break;
case JsonToken.EndObject:
return jsonValue;
default:
throw new JsonSerializationException(string.Format("Unknown token {0} at path: {1} ", reader.TokenType, reader.Path));
}
}
throw new JsonSerializationException(string.Format("Unclosed object at path: {0}", reader.Path));
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var jsonValue = (JsonValueList)value;
writer.WriteStartObject();
foreach (var pair in jsonValue.Values)
{
writer.WritePropertyName(pair.Key);
writer.WriteValue(pair.Value);
}
writer.WriteEndObject();
}
}
注意[JsonConverter(typeof(JsonValueListConverter))] 的使用。这指定在序列化和反序列化JsonValueList 时使用自定义转换器。
接下来,如下定义您的Update_DB 类:
[DataContract]
public class Update_DB
{
[DataMember(Name = "appname", IsRequired = true)]
public string appname { get; set; }
[DataMember]
public string key { get; set; }
[DataMember(Name = "data", IsRequired = true)]
public List<JsonValueList> data { get; set; }
[DataMember]
public string updateId { get; set; }
[DataMember]
public string updateTS { get; set; }
[DataMember]
public string creationUser { get; set; }
}
现在您将能够成功地序列化和反序列化您的 JSON。示例fiddle。
更新
如果你没有重复的键,你可以如下定义你的类:
[DataContract]
public class Update_DB
{
[DataMember(Name = "appname", IsRequired = true)]
public string appname { get; set; }
[DataMember]
public string key { get; set; }
[DataMember(Name = "data", IsRequired = true)]
public List<Dictionary<string, string>> data { get; set; }
[DataMember]
public string updateId { get; set; }
[DataMember]
public string updateTS { get; set; }
[DataMember]
public string creationUser { get; set; }
}
然后是以下内容:
var collection = new Update_DB
{
data = new List<Dictionary<string, string>>
{
new Dictionary<string, string>
{
{"data1", "10551296"},
{"data2", "TrainingIns"},
{"data3", "Completed"},
},
new Dictionary<string, string>
{
{"connectorType", "webserver-to-appserver"},
{"sourceUri", "data4"},
{"destinationUri", "data5"},
},
},
};
string x = JsonConvert.SerializeObject(collection.data, Formatting.Indented);
Console.WriteLine(x);
产生输出:
[
{
"data1": "10551296",
"data2": "TrainingIns",
"data3": "Completed"
},
{
"connectorType": "webserver-to-appserver",
"sourceUri": "data4",
"destinationUri": "data5"
}
]
示例fiddle。