How can I serialize/deserialize a kind of json mixing object and list of object at the same level in c#?

huangapple go评论93阅读模式
英文:

How can I serialize/deserialize a kind of json mixing object and list of object at the same level in c#?

问题

我正在使用Newtonsoft JSON,并且需要序列化/反序列化这种类型的JSON:

  1. [
  2. {
  3. "value": "value1",
  4. "field": "field1"
  5. },
  6. {
  7. "value": "value2",
  8. "field": "field2"
  9. },
  10. {
  11. "value": "value3",
  12. "field": "field3"
  13. },
  14. [
  15. {
  16. "value": "value4",
  17. "field": "field4"
  18. },
  19. {
  20. "value": "value4",
  21. "field": "field5"
  22. }
  23. ]
  24. ]

正如您所见,我可以在同一级别同时拥有一个对象或这个对象的列表。我已经为该对象创建了一个类,但我不知道如何使序列化过程处理这种类型的JSON,或者是否可以这样做。

编辑:我没有选择处理我收到的JSON。因此,请不要认为我喜欢这样做,如果您这么认为,是错误的。

英文:

I'm using newtonsoft json, and I need to serialize/deserialize this kind of json:

  1. [
  2. {
  3. "value": "value1",
  4. "field": "field1"
  5. },
  6. {
  7. "value": "value2",
  8. "field": "field2"
  9. },
  10. {
  11. "value": "value3",
  12. "field": "field3"
  13. },
  14. [
  15. {
  16. "value": "value4",
  17. "field": "field4"
  18. },
  19. {
  20. "value": "value4",
  21. "field": "field5"
  22. }
  23. ]
  24. ]

As you can see, I can have an object or a list of this object at the same level. I've created a class for the object but I don't know how to make the serialization process this kind of json, or if it's possible to do.

EDIT: I don't have the choice to process that json as it comes to me. So please, if you think I like this, you're wrong.

答案1

得分: 1

你可以创建一个自定义的JSON转换器:

  1. Result result = JsonConvert.DeserializeObject<Result>(json, new ArrayJsonConverter());

以下是自定义的ArrayJsonConverter类:

  1. public class ArrayJsonConverter : JsonConverter<Result>
  2. {
  3. public override Result ReadJson(JsonReader reader, Type objectType, Result existingValue, bool hasExistingValue, JsonSerializer serializer)
  4. {
  5. JArray jArr = JArray.Load(reader);
  6. var result = new Result { Items = new List<Item>(), ListItems = new List<List<Item>>() };
  7. foreach (var item in jArr)
  8. if (item.Type == JTokenType.Array) result.ListItems.Add(item.ToObject<List<Item>>());
  9. else result.Items.Add(item.ToObject<Item>());
  10. return result;
  11. }
  12. public override void WriteJson(JsonWriter writer, Result value, JsonSerializer serializer)
  13. {
  14. throw new NotImplementedException();
  15. }
  16. }

接下来是Result类:

  1. public class Result
  2. {
  3. public List<Item> Items { get; set; }
  4. public List<List<Item>> ListItems { get; set; }
  5. }

最后是Item类:

  1. public class Item
  2. {
  3. public string value { get; set; }
  4. public string field { get; set; }
  5. }
英文:

you can create a custom json converter

  1. Result result = JsonConvert.DeserializeObject&lt;Result&gt;(json, new ArrayJsonConverter())
  2. public class ArrayJsonConverter : JsonConverter&lt;Result&gt;
  3. {
  4. public override Result ReadJson(JsonReader reader, Type objectType, Result existingValue, bool hasExistingValue, JsonSerializer serializer)
  5. {
  6. JArray jArr = JArray.Load(reader);
  7. var result = new Result { Items = new List&lt;Item&gt;(), ListItems = new List&lt;List&lt;Item&gt;&gt;() };
  8. foreach (var item in jArr)
  9. if (item.Type == JTokenType.Array) result.ListItems.Add(item.ToObject&lt;List&lt;Item&gt;&gt;());
  10. else result.Items.Add(item.ToObject&lt;Item&gt;());
  11. return result;
  12. }
  13. public override void WriteJson(JsonWriter writer, Result value, JsonSerializer serializer)
  14. {
  15. throw new NotImplementedException();
  16. }
  17. }
  18. public class Result
  19. {
  20. public List&lt;Item&gt; Items { get; set; }
  21. public List&lt;List&lt;Item&gt;&gt; ListItems { get; set; }
  22. }
  23. public class Item
  24. {
  25. public string value { get; set; }
  26. public string field { get; set; }
  27. }

答案2

得分: 0

以下是我找到的解决方案,感谢您的帮助:

  1. public class Item
  2. {
  3. public string Value { get; set; }
  4. public string Field { get; set; }
  5. }
  6. public class ItemContainer
  7. {
  8. public List<Item> Items { get; set; }
  9. public List<List<Item>> NestedItems { get; set; }
  10. }
  11. public class ItemContainerConverter : JsonConverter<ItemContainer>
  12. {
  13. public override ItemContainer ReadJson(JsonReader reader, Type objectType, ItemContainer existingValue,
  14. bool hasExistingValue, JsonSerializer serializer)
  15. {
  16. var jsonObject = JArray.Load(reader);
  17. var itemContainer = new ItemContainer
  18. {
  19. Items = new List<Item>(),
  20. NestedItems = new List<List<Item>>()
  21. };
  22. foreach (var token in jsonObject)
  23. {
  24. if (token.Type == JTokenType.Array)
  25. {
  26. var nestedItemList = token.ToObject<List<Item>>();
  27. itemContainer.NestedItems.Add(nestedItemList);
  28. }
  29. else if (token.Type == JTokenType.Object)
  30. {
  31. var item = token.ToObject<Item>();
  32. itemContainer.Items.Add(item);
  33. }
  34. }
  35. return itemContainer;
  36. }
  37. public override void WriteJson(JsonWriter writer, ItemContainer value, JsonSerializer serializer)
  38. {
  39. writer.WriteStartArray();
  40. foreach (var item in value.Items)
  41. {
  42. serializer.Serialize(writer, item);
  43. }
  44. if (value.NestedItems != null && value.NestedItems.Any())
  45. {
  46. writer.WriteStartArray();
  47. foreach (var nestedItem in value.NestedItems.SelectMany(nestedList => nestedList))
  48. {
  49. serializer.Serialize(writer, nestedItem);
  50. }
  51. writer.WriteEndArray();
  52. }
  53. writer.WriteEndArray();
  54. }
  55. }

以下是如何使用它的方式:

  1. var settings = new JsonSerializerSettings()
  2. {
  3. ContractResolver = new DefaultContractResolver
  4. {
  5. NamingStrategy = new SnakeCaseNamingStrategy()
  6. }
  7. };
  8. settings.Converters.Add(new ItemContainerConverter());
  9. var rootObject = JsonConvert.DeserializeObject<ItemContainer>(jsonString, settings);
  10. var json = JsonConvert.SerializeObject(rootObject, settings);

希望这对您有所帮助!如果您有任何其他问题,请随时提出。

英文:

Here is the solution I found thanks to your help:

  1. public class Item
  2. {
  3. public string Value { get; set; }
  4. public string Field { get; set; }
  5. }
  6. public class ItemContainer
  7. {
  8. public List&lt;Item&gt; Items { get; set; }
  9. public List&lt;List&lt;Item&gt;&gt; NestedItems { get; set; }
  10. }
  11. public class ItemContainerConverter : JsonConverter&lt;ItemContainer&gt;
  12. {
  13. public override ItemContainer ReadJson(JsonReader reader, Type objectType, ItemContainer existingValue,
  14. bool hasExistingValue, JsonSerializer serializer)
  15. {
  16. var jsonObject = JArray.Load(reader);
  17. var itemContainer = new ItemContainer
  18. {
  19. Items = new List&lt;Item&gt;(),
  20. NestedItems = new List&lt;List&lt;Item&gt;&gt;()
  21. };
  22. foreach (var token in jsonObject)
  23. {
  24. if (token.Type == JTokenType.Array)
  25. {
  26. var nestedItemList = token.ToObject&lt;List&lt;Item&gt;&gt;();
  27. itemContainer.NestedItems.Add(nestedItemList);
  28. }
  29. else if (token.Type == JTokenType.Object)
  30. {
  31. var item = token.ToObject&lt;Item&gt;();
  32. itemContainer.Items.Add(item);
  33. }
  34. }
  35. return itemContainer;
  36. }
  37. public override void WriteJson(JsonWriter writer, ItemContainer value, JsonSerializer serializer)
  38. {
  39. writer.WriteStartArray();
  40. foreach (var item in value.Items)
  41. {
  42. serializer.Serialize(writer, item);
  43. }
  44. if (value.NestedItems != null &amp;&amp; value.NestedItems.Any())
  45. {
  46. writer.WriteStartArray();
  47. foreach (var nestedItem in value.NestedItems.SelectMany(nestedList =&gt; nestedList))
  48. {
  49. serializer.Serialize(writer, nestedItem);
  50. }
  51. writer.WriteEndArray();
  52. }
  53. writer.WriteEndArray();
  54. }
  55. }

And there is how to use it:

  1. var settings = new JsonSerializerSettings()
  2. {
  3. ContractResolver = new DefaultContractResolver
  4. {
  5. NamingStrategy = new SnakeCaseNamingStrategy()
  6. }
  7. };
  8. settings.Converters.Add(new ItemContainerConverter());
  9. var rootObject = JsonConvert.DeserializeObject&lt;ItemContainer&gt;(jsonString, settings);
  10. var json = JsonConvert.SerializeObject(rootObject, settings);

huangapple
  • 本文由 发表于 2023年7月4日 21:27:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613143.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定