如何在反序列化中跳过属性名称



我正在尝试从第三方服务反序列化json

{
"route1":[
{
"Id":1
}
],
"route2":{
"error":"Id not found"
}
}

它是一个Dictionary,但值可以是数组或对象。我需要唯一的数组,所以当我在JsonConverter中找到一个对象时,我决定放一个空数组。

public class Item
{
public int Id { get; set; }
}
public class JsonInfo
{
[JsonConverter(typeof(ItemConverter))]
public List<Item> Items{ get; set; }
}
public class ItemConverter : Newtonsoft.Json.JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.String:
case JsonToken.StartObject:
return new List<Item>();
case JsonToken.StartArray:
var array = JArray.Load(reader);
var data = array.Select(ParseValue).ToList();
return data;
default:
return null;
}
}
public override bool CanConvert(Type objectType)
{
return false;
}
private Item ParseValue(JToken value)
{
switch (value.Type)
{
case JTokenType.Object:
return value.ToObject<Item>();
default:
return null;
}
}
}

但当我试图反序列化Dictionary<string, JsonInfo>时,它会引发一个错误(必须是json数组(。我认为转换器试图在json中找到JsonInfo属性,而不是在这个类中找到数组的问题。

也许我错过了什么
我们有允许跳过属性名称的属性吗?

您不需要创建自定义转换器。

您可以通过以下几行代码实现相同的功能:

var semiParsedJson = JObject.Parse(rawJson);
var result = new Dictionary<string, List<Item>>(); 
foreach (var item in semiParsedJson)
if (item.Value is JArray)
result.Add(item.Key, item.Value.ToObject<List<Item>>());
else 
result.Add(item.Key, new List<Item>>());
  1. 我们将json半解析为JObject
  2. 我们通过一个简单的foreach迭代其属性,其中项的类型为KeyValuePair<string, JToken?>
  3. 如果ValueJArray(而不是JObject(,那么我们简单地用Value的内容填充字典
  4. 最后,我们让Newtonsoft代表我们将Value转换为List<Item>集合

使用这种方法,您不需要编写自定义转换器,也不需要用序列化属性装饰域模型。

我解决了我的问题,不是将自定义转换器应用于属性,而是应用于整个类

[JsonConverter(typeof(ItemConverter))]
public class JsonInfo
{
public List<Item> Items{ get; set; }
}
public class ItemConverter: JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.String:
return null;
case JsonToken.StartObject:
reader.Skip();
return new JsonInfo{ Items = new List<Item>() };
case JsonToken.StartArray:
var array = JArray.Load(reader);
var data = array.Select(ParseValue).ToList();
return new JsonInfo{ Items = data };
default:
return null;
}
}
public override bool CanConvert(Type objectType)
{
return false;
}
private Item ParseValue(JToken value)
{
switch (value.Type)
{
case JTokenType.Object:
return value.ToObject<Item>();
default:
return null;
}
}
}

相关内容

  • 没有找到相关文章

最新更新