如何在C#中运行一个转换器以处理复杂JSON文件中的多格式内容?

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

How do I run a converter within another converter to handle multi-format content in a complex JSON file in C#?

问题

I am trying to deserialize a JSON file with a complex structure in C#, but I'm facing difficulties due to multi-format content within arrays. Unfortunately, I cannot change the JSON format. Here's an example of the JSON file:

  1. {
  2. "messages": [
  3. {
  4. "date": "2023-05-19T17:58:17.329Z",
  5. "message": {
  6. "alert": {
  7. "type": "info",
  8. "message": [
  9. {
  10. "name": "AshesAppTest1",
  11. "argType": "nonAvatarPlayer"
  12. },
  13. " has connected to the game server"
  14. ]
  15. }
  16. },
  17. "activePlayer": null
  18. },
  19. {
  20. "date": "2023-05-19T18:56:32.304Z",
  21. "message": [
  22. {
  23. "name": "AshesAppTest2",
  24. "argType": "player"
  25. },
  26. " ",
  27. "Hello world!"
  28. ]
  29. }
  30. ]
  31. }

To handle this complex JSON structure, I've created the following C# class structure and a custom converter:

  1. public class GamePlayMessage
  2. {
  3. public string date { get; set; }
  4. public GamePlayPlayer activePlayer { get; set; }
  5. [JsonProperty("message")]
  6. [JsonConverter(typeof(GamePlayMessageDataConverter))]
  7. public GamePlayMessageData MessageData { get; set; }
  8. }
  9. public class GamePlayMessageData
  10. {
  11. [JsonProperty("alert")]
  12. public GamePlayComplexMessage ComplexMessage { get; set; }
  13. }
  14. public class GamePlayComplexMessage
  15. {
  16. public string type;
  17. public List<object> message;
  18. }
  19. class GamePlayMessageDataConverter : JsonConverter
  20. {
  21. public override bool CanConvert(Type objectType)
  22. {
  23. return (objectType == typeof(GamePlayMessageData));
  24. }
  25. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  26. {
  27. JToken token = JToken.Load(reader);
  28. if (token.Type == JTokenType.Object)
  29. {
  30. return token.ToObject<GamePlayMessageData>();
  31. }
  32. else if (token.Type == JTokenType.Array)
  33. {
  34. Debug.Log(token);
  35. return new GamePlayMessageData
  36. {
  37. ComplexMessage = new GamePlayComplexMessage
  38. {
  39. type = "noType",
  40. message = new List<object>(token.ToArray<object>())
  41. }
  42. };
  43. }
  44. return null;
  45. }
  46. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  47. {
  48. serializer.Serialize(writer, value);
  49. }
  50. }

The above code works fine until the line message = new List(token.ToArray()), where I need to utilize another converter. I'm not sure how to run a converter within another converter. Could you please assist me in achieving this? Thank you in advance for your help.

英文:

I am trying to deserialize a JSON file with a complex structure in C#, but I'm facing difficulties due to multi-format content within arrays. Unfortunately, I cannot change the JSON format. Here's an example of the JSON file:

  1. {
  2. &quot;messages&quot;: [
  3. {
  4. &quot;date&quot;: &quot;2023-05-19T17:58:17.329Z&quot;,
  5. &quot;message&quot;: {
  6. &quot;alert&quot;: {
  7. &quot;type&quot;: &quot;info&quot;,
  8. &quot;message&quot;: [
  9. {
  10. &quot;name&quot;: &quot;AshesAppTest1&quot;,
  11. &quot;argType&quot;: &quot;nonAvatarPlayer&quot;
  12. },
  13. &quot; has connected to the game server&quot;
  14. ]
  15. }
  16. },
  17. &quot;activePlayer&quot;: null
  18. },
  19. {
  20. &quot;date&quot;: &quot;2023-05-19T18:56:32.304Z&quot;,
  21. &quot;message&quot;: [
  22. {
  23. &quot;name&quot;: &quot;AshesAppTest2&quot;,
  24. &quot;argType&quot;: &quot;player&quot;
  25. },
  26. &quot; &quot;,
  27. &quot;Hello world!&quot;
  28. ]
  29. }
  30. ]
  31. }

To handle this complex JSON structure, I've created the following C# class structure and a custom converter:

  1. public class GamePlayMessage
  2. {
  3. public string date { get; set; }
  4. public GamePlayPlayer activePlayer { get; set; }
  5. [JsonProperty(&quot;message&quot;)]
  6. [JsonConverter(typeof(GamePlayMessageDataConverter))]
  7. public GamePlayMessageData MessageData { get; set; }
  8. }
  9. public class GamePlayMessageData
  10. {
  11. [JsonProperty(&quot;alert&quot;)]
  12. public GamePlayComplexMessage ComplexMessage { get; set; }
  13. }
  14. public class GamePlayComplexMessage
  15. {
  16. public string type;
  17. public List&lt;object&gt; message;
  18. }
  19. class GamePlayMessageDataConverter : JsonConverter
  20. {
  21. public override bool CanConvert(Type objectType)
  22. {
  23. return (objectType == typeof(GamePlayMessageData));
  24. }
  25. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
  26. {
  27. JToken token = JToken.Load(reader);
  28. if (token.Type == JTokenType.Object)
  29. {
  30. return token.ToObject&lt;GamePlayMessageData&gt;();
  31. }
  32. else if (token.Type == JTokenType.Array)
  33. {
  34. Debug.Log(token);
  35. return new GamePlayMessageData
  36. {
  37. ComplexMessage = new GamePlayComplexMessage
  38. {
  39. type = &quot;noType&quot;,
  40. message = new List&lt;object&gt;(token.ToArray&lt;object&gt;())
  41. }
  42. };
  43. }
  44. return null;
  45. }
  46. public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
  47. {
  48. serializer.Serialize(writer, value);
  49. }
  50. }

The above code works fine until the line message = new List<object>(token.ToArray<object>()), where I need to utilize another converter. I'm not sure how to run a converter within another converter. Could you please assist me in achieving this? Thank you in advance for your help.

答案1

得分: 1

Here is the code you provided translated into Chinese:

  1. 我会创建类似这样的代码

var data = JsonConvert.DeserializeObject<数据>(json);

class GamePlayMessageDataConverter : JsonConverter
{
public override GamePlayMessageData ReadJson(JsonReader reader, Type objectType, GamePlayMessageData existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);

  1. GamePlayMessageData data = null;
  2. if (token.Type == JTokenType.Object)
  3. {
  4. data = token.ToObject<GamePlayMessageData>();
  5. }
  6. else if (token.Type == JTokenType.Array)
  7. {
  8. data = new GamePlayMessageData
  9. {
  10. ComplexMessage = new GamePlayComplexMessage
  11. {
  12. type = "noType",
  13. message = token.ToObject<List<object>>()
  14. }
  15. };
  16. }
  17. if (data != null)
  18. for (int i = 0; i < data.ComplexMessage.message.Count; i++)
  19. {
  20. if (data.ComplexMessage.message[i].GetType().ToString() ==
  21. "Newtonsoft.Json.Linq.JObject")
  22. data.ComplexMessage.message[i] =
  23. ((JObject)data.ComplexMessage.message[i]).ToObject<参数>();
  24. }
  25. return data;
  26. }
  27. public override void WriteJson(JsonWriter writer, GamePlayMessageData value, JsonSerializer serializer)
  28. {
  29. serializer.Serialize(writer, value);
  30. }

}

  1. 测试

Console.WriteLine(data.Messages[0].MessageData.ComplexMessage.message[0]
.GetType().ToString()); // "参数"

public partial class 数据
{
[JsonProperty("messages")]
public List Messages { get; set; }
}

public class GamePlayMessage
{
public string date { get; set; }
public GamePlayPlayer activePlayer { get; set; }

  1. [JsonProperty("message")]
  2. [JsonConverter(typeof(GamePlayMessageDataConverter))]
  3. public GamePlayMessageData MessageData { get; set; }

}

public class GamePlayMessageData
{
[JsonProperty("alert")]
public GamePlayComplexMessage ComplexMessage { get; set; }
}

public class GamePlayComplexMessage
{
public string type;
public List message;
}

public partial class 参数
{
[JsonProperty("name")]
public string Name { get; set; }

  1. [JsonProperty("argType")]
  2. public string ArgType { get; set; }

}

  1. Please note that I have translated the code as requested, including class and property names.
  2. <details>
  3. <summary>英文:</summary>
  4. I would create code like this

var data = JsonConvert.DeserializeObject<Data>(json);

class GamePlayMessageDataConverter : JsonConverter<GamePlayMessageData>
{
public override GamePlayMessageData ReadJson(JsonReader reader, Type objectType, GamePlayMessageData existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);

  1. GamePlayMessageData data = null;
  2. if (token.Type == JTokenType.Object)
  3. {
  4. data = token.ToObject&lt;GamePlayMessageData&gt;();
  5. }
  6. else if (token.Type == JTokenType.Array)
  7. {
  8. data = new GamePlayMessageData
  9. {
  10. ComplexMessage = new GamePlayComplexMessage
  11. {
  12. type = &quot;noType&quot;,
  13. message = token.ToObject&lt;List&lt;object&gt;&gt;()
  14. }
  15. };
  16. }
  17. if (data != null)
  18. for (int i = 0; i &lt; data.ComplexMessage.message.Count; i++)
  19. {
  20. if (data.ComplexMessage.message[i].GetType().ToString() ==
  21. &quot;Newtonsoft.Json.Linq.JObject&quot;)
  22. data.ComplexMessage.message[i] =
  23. ((JObject)data.ComplexMessage.message[i]).ToObject&lt;Arg&gt;();
  24. }
  25. return data;
  26. }
  27. public override void WriteJson(JsonWriter writer, GamePlayMessageData value, JsonSerializer serializer)
  28. {
  29. serializer.Serialize(writer, value);
  30. }

}

  1. test

Console.WriteLine(data.Messages[0].MessageData.ComplexMessage.message[0]
.GetType().ToString()); // "Arg"

  1. classes

public partial class Data
{
[JsonProperty("messages")]
public List<GamePlayMessage> Messages { get; set; }
}

public class GamePlayMessage
{
public string date { get; set; }
public GamePlayPlayer activePlayer { get; set; }

  1. [JsonProperty(&quot;message&quot;)]
  2. [JsonConverter(typeof(GamePlayMessageDataConverter))]
  3. public GamePlayMessageData MessageData { get; set; }

}

public class GamePlayMessageData
{
[JsonProperty("alert")]
public GamePlayComplexMessage ComplexMessage { get; set; }
}

public class GamePlayComplexMessage
{
public string type;
public List<object> message;
}

public partial class Arg
{
[JsonProperty("name")]
public string Name { get; set; }

  1. [JsonProperty(&quot;argType&quot;)]
  2. public string ArgType { get; set; }

}

huangapple
  • 本文由 发表于 2023年5月21日 08:13:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76297817.html
匿名

发表评论

匿名网友

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

确定

  • 开发者交流平台

    本页二维码