英文:
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:
{
"messages": [
{
"date": "2023-05-19T17:58:17.329Z",
"message": {
"alert": {
"type": "info",
"message": [
{
"name": "AshesAppTest1",
"argType": "nonAvatarPlayer"
},
" has connected to the game server"
]
}
},
"activePlayer": null
},
{
"date": "2023-05-19T18:56:32.304Z",
"message": [
{
"name": "AshesAppTest2",
"argType": "player"
},
" ",
"Hello world!"
]
}
]
}
To handle this complex JSON structure, I've created the following C# class structure and a custom converter:
public class GamePlayMessage
{
public string date { get; set; }
public GamePlayPlayer activePlayer { get; set; }
[JsonProperty("message")]
[JsonConverter(typeof(GamePlayMessageDataConverter))]
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;
}
class GamePlayMessageDataConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(GamePlayMessageData));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Object)
{
return token.ToObject<GamePlayMessageData>();
}
else if (token.Type == JTokenType.Array)
{
Debug.Log(token);
return new GamePlayMessageData
{
ComplexMessage = new GamePlayComplexMessage
{
type = "noType",
message = new List<object>(token.ToArray<object>())
}
};
}
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
The above code works fine until the line message = new List
英文:
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:
{
"messages": [
{
"date": "2023-05-19T17:58:17.329Z",
"message": {
"alert": {
"type": "info",
"message": [
{
"name": "AshesAppTest1",
"argType": "nonAvatarPlayer"
},
" has connected to the game server"
]
}
},
"activePlayer": null
},
{
"date": "2023-05-19T18:56:32.304Z",
"message": [
{
"name": "AshesAppTest2",
"argType": "player"
},
" ",
"Hello world!"
]
}
]
}
To handle this complex JSON structure, I've created the following C# class structure and a custom converter:
public class GamePlayMessage
{
public string date { get; set; }
public GamePlayPlayer activePlayer { get; set; }
[JsonProperty("message")]
[JsonConverter(typeof(GamePlayMessageDataConverter))]
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;
}
class GamePlayMessageDataConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(GamePlayMessageData));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Object)
{
return token.ToObject<GamePlayMessageData>();
}
else if (token.Type == JTokenType.Array)
{
Debug.Log(token);
return new GamePlayMessageData
{
ComplexMessage = new GamePlayComplexMessage
{
type = "noType",
message = new List<object>(token.ToArray<object>())
}
};
}
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
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:
我会创建类似这样的代码
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);
GamePlayMessageData data = null;
if (token.Type == JTokenType.Object)
{
data = token.ToObject<GamePlayMessageData>();
}
else if (token.Type == JTokenType.Array)
{
data = new GamePlayMessageData
{
ComplexMessage = new GamePlayComplexMessage
{
type = "noType",
message = token.ToObject<List<object>>()
}
};
}
if (data != null)
for (int i = 0; i < data.ComplexMessage.message.Count; i++)
{
if (data.ComplexMessage.message[i].GetType().ToString() ==
"Newtonsoft.Json.Linq.JObject")
data.ComplexMessage.message[i] =
((JObject)data.ComplexMessage.message[i]).ToObject<参数>();
}
return data;
}
public override void WriteJson(JsonWriter writer, GamePlayMessageData value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
测试
Console.WriteLine(data.Messages[0].MessageData.ComplexMessage.message[0]
.GetType().ToString()); // "参数"
类
public partial class 数据
{
[JsonProperty("messages")]
public List
}
public class GamePlayMessage
{
public string date { get; set; }
public GamePlayPlayer activePlayer { get; set; }
[JsonProperty("message")]
[JsonConverter(typeof(GamePlayMessageDataConverter))]
public GamePlayMessageData MessageData { get; set; }
}
public class GamePlayMessageData
{
[JsonProperty("alert")]
public GamePlayComplexMessage ComplexMessage { get; set; }
}
public class GamePlayComplexMessage
{
public string type;
public List
}
public partial class 参数
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("argType")]
public string ArgType { get; set; }
}
Please note that I have translated the code as requested, including class and property names.
<details>
<summary>英文:</summary>
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);
GamePlayMessageData data = null;
if (token.Type == JTokenType.Object)
{
data = token.ToObject<GamePlayMessageData>();
}
else if (token.Type == JTokenType.Array)
{
data = new GamePlayMessageData
{
ComplexMessage = new GamePlayComplexMessage
{
type = "noType",
message = token.ToObject<List<object>>()
}
};
}
if (data != null)
for (int i = 0; i < data.ComplexMessage.message.Count; i++)
{
if (data.ComplexMessage.message[i].GetType().ToString() ==
"Newtonsoft.Json.Linq.JObject")
data.ComplexMessage.message[i] =
((JObject)data.ComplexMessage.message[i]).ToObject<Arg>();
}
return data;
}
public override void WriteJson(JsonWriter writer, GamePlayMessageData value, JsonSerializer serializer)
{
serializer.Serialize(writer, value);
}
}
test
Console.WriteLine(data.Messages[0].MessageData.ComplexMessage.message[0]
.GetType().ToString()); // "Arg"
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; }
[JsonProperty("message")]
[JsonConverter(typeof(GamePlayMessageDataConverter))]
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; }
[JsonProperty("argType")]
public string ArgType { get; set; }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论