此问题源自另一个主题,可在以下位置找到: Extract objects from JSON array to list
问题是我收到了以下JSON响应,而我的JSON.NET反序列化程序并不理解它,但其他几个JSON验证程序(如https://jsonlint.com)表示它是有效的。
[
{"value":"{\"code\":\"MO\",\"description\":\"Monday\",\"isSet\":false}","nr":1}
,{"value":"{\"code\":\"TU\",\"description\":\"Tuesday\",\"isSet\":true}","nr":2}
]
在我看来,这里的问题是值对象看起来像一个JSON对象,但实际上是一个字符串。 JsonConvert.DeserializeObject不断抛出错误,直到我删除其他引号(“)和转义字符。
所以问题是,为什么这个响应的格式是这样的?如何告诉解串器如何使用它?我确信删除或替换字符不是要走的路。
以下是我正在做的事情:
public class Value
{
public string code { get; set; }
public string description { get; set; }
public bool isSet { get; set; }
}
public class RootObject
{
public Value value { get; set; }
public int nr { get; set; }
}
var json = JsonConvert.DeserializeObject<List<RootObject>>(serviceResult);
以上不起作用。
目前我已经用这种方式解决了这个问题。但我一直认为上面的解串器更优雅。
JArray jArray = JArray.Parse(serviceResult);
List<Value> values = jArray.Select(x => JObject.Parse(x["value"].ToString()).ToObject<Value>()).ToList();
答案 0 :(得分:1)
最简单的方法是使用自定义JsonConverter
,例如:
public class StringToObjectConverter<T> : Newtonsoft.Json.JsonConverter
{
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
//This will only be needed if you also need to serlialise
writer.WriteRaw(JsonConvert.SerializeObject(value));
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
return JsonConvert.DeserializeObject<T>(reader.Value.ToString());
}
public override bool CanRead => true;
//We can only work with the type T, you could expand this to cope with derived types
public override bool CanConvert(Type objectType) => typeof(T) == objectType;
}
现在使用这些模型,特别注意Value
属性的属性:
public class RootObject
{
[JsonConverter(typeof(StringToObjectConverter<Value>))]
public Value value { get; set; }
public int nr { get; set; }
}
public class Value
{
public string code { get; set; }
public string description { get; set; }
public bool isSet { get; set; }
}
现在它是一个简单的反序列化:
var json = "....";
var rootObjects = JsonConvert.DeserializeObject<List<RootObject>>(json);