将json反序列化为c#-objects时出现以下问题。
我有一个json-string,就像这样:
string data =
@"{
'response':
[
3,
{
'id': 1,
'name': 'john'
},
{
'id': 1,
'name': 'john'
},
{
'id': 1,
'name': 'john'
}
]
}";
用于反序列化的类:
class Response
{
[JsonProperty(PropertyName = "response")]
Item[] Items {get; set; }
}
class Item
{
[JsonProperty(PropertyName = "id")]
public int Id{get; set; }
[JsonProperty(PropertyName = "name")]
public int Id{get; set; }
}
然后我尝试反序列化它:
var res = JsonConvert.DeserializeObject<Response>(data);
反序列化会引发一个异常,并显示以下消息:“将值3转换为'Item'时出错。路径'响应[0]',第1行,第19位。” Obvioiusly它发生,因为数据字符串中的数组'响应'包含描述响应长度的文字“3”。我想知道,如果不通过json.net编写自定义反序列化逻辑,我可以正确地进行反序列化吗?或者我需要创建自定义反序列化逻辑?
答案 0 :(得分:3)
首先,你的模型应该稍微纠正一下
public class Response
{
[JsonProperty(PropertyName = "response")]
Item[] Items { get; set; }
}
public class Item
{
[JsonProperty(PropertyName = "id")]
public int Id { get; set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
}
如果从json中删除3
,则此反序列化将正常工作
var result = JsonConvert.DeserializeObject<Response>(json);
如果它来自服务器,您无法控制它,那么您可以编写自定义转换器
public class CustomConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Item);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.Value is long)
{
reader.Read(); //Skip this 3
serializer.Converters.Remove(this); //avoid infinite recursion
}
return serializer.Deserialize<Item>(reader);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
并反序列化为
var result = JsonConvert.DeserializeObject<Response>(json, new CustomConverter());
您甚至可以使用Linq获取Items
var items = JObject.Parse(json)["response"]
.Skip(1)
.OfType<JObject>()
.Select(j=>j.ToObject<Item>())
.ToList();
答案 1 :(得分:0)
另一种方法,
class Response
{
[JsonProperty(PropertyName = "response")]
public dynamic Items { get; set; }
}
var des = JsonConvert.DeserializeObject<Response>(data);
var result = (des.Items as IEnumerable<Newtonsoft.Json.Linq.JToken>)
.Select(delegate(JToken j){
if (j.Type == JTokenType.Integer)
return j.Value<int>();
return JsonConvert.DeserializeObject<object>(j.ToString());
}).ToList();
var one = JsonConvert.DeserializeObject<Item>(result[1].ToString());