问题描述
我想分析Telegram-Chats,所以我以JSON格式导出了聊天,并想将其反序列化到我的分析软件中.
I wanted to analyze Telegram-Chats so I exported a chat in JSON format and wanted to deserialize it into my analyzing software.
{
"id": 397910,
"type": "message",
"date": "2018-02-21T10:27:59",
"edited": "1970-01-01T01:00:00",
"from": "Username",
"from_id": 39033284,
"text": "Some Text"
}
所以我用了这个简单的代码来读取JSON
So I've used this simple code to read the JSON
List<JSONObject> jsonObjects = JsonConvert.DeserializeObject<List<JSONObject>>(File.ReadAllText(openFileDialog.FileName));
public class JSONObject
{
public int ID;
public string type;
public string date;
public string edited;
public string from;
public int fromID;
public string photo;
public int width;
public int height;
public string text;
}
这对于前525个数据集来说非常顺利,但是之后,由于一致性问题",我在反序列化数据时遇到了麻烦.文本的数据类型有时会更改为数组.
This went very well for the first 525 datasets but afterwards, I had trouble deserializing the data because of "consistency issues". The Datatype of the text sometimes changes to an array.
{
"id": 397911,
"type": "message",
"date": "2018-02-21T10:31:47",
"edited": "1970-01-01T01:00:00",
"from": "Username",
"from_id": 272964614,
"text": [
"Some Text ",
{
"type": "mention",
"text": "@school"
},
" Some Text"
]
}
我也找到了这个数据集
{
"id": 397904,
"type": "message",
"date": "2018-02-21T10:18:12",
"edited": "1970-01-01T01:00:00",
"from": "Username",
"from_id": 39033284,
"text": [
{
"type": "link",
"text": "google.com"
},
"\n\nSome Text"
]
}
当数据显示出这种不一致时,我不知道如何反序列化数据.
I don't know how I deserialize the data when it shows this kind of inconsistency.
推荐答案
由于属性很复杂,因此您需要编写自己的反序列化逻辑.
as your property is complex, you'll need to write your own de-serialization logic.
这是我的,但这只是一个例子:
Here's mine, but it's just an example :
- 首先,您的text属性似乎是
- 单个值
- 或值数组
- First of all, your text property seems to be
- A single value
- Or an array of values
在这种情况下,我将获得始终列表"结果,具有单个值的情况将只是具有一个条目的列表.
In this case, I'll go for an "always list" result, the case with a single value will just be a list with one entry.
public List<TextProperty> text;
- 该值也可以是
- 单个字符串值
- 具有字符串值和元数据(文本类型)的对象
- The value can also be
- A single string value
- An object with the string value and a meta datum (text type)
同样,如果是字符串,我会去找一个没有类型的总是对象"
Again, I'll go for an "always object" with no type if it's string only
public class TextProperty { public string text { get; set; } public string type { get; set; } }
然后,您必须创建自己的Converter来处理此问题,您只需从JsonConverter继承并实现逻辑
Then you have to make your own Converter to handle this, you just have to inherit from JsonConverter and implement the logic
public class TextPropertyConverter : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); // not covered here } // A value can be either single string or object // Return a TextProperty in both cases private TextProperty ParseValue(JToken value) { switch(value.Type) { case JTokenType.String: return new TextProperty { text = value.ToObject<string>() }; case JTokenType.Object: return value.ToObject<TextProperty>(); default: return null; } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // You'll start either with a single value (we'll convert to list of one value) or an array (list of several values then) switch(reader.TokenType) { case JsonToken.String: case JsonToken.StartObject: return new List<TextProperty> { ParseValue(JToken.Load(reader)) }; case JsonToken.StartArray: var a = JArray.Load(reader); var l = new List<TextProperty>(); foreach(var v in a) l.Add(ParseValue(v)); return l; default: return null; } } public override bool CanConvert(Type objectType) => false; }
我认为所有情况都应该涵盖
I think all cases should be covered
要使用它,只需将JsonConverter属性添加到目标属性
To use it, simply add the JsonConverter attribute to the target property
public class JSONObject { public int id; public string type; public string date; public string edited; public string from; public int from_id; public string photo; public int width; public int height; [JsonConverter(typeof(TextPropertyConverter))] public List<TextProperty> text; }
然后对其进行测试:
static void Main(string[] args) { string json = @" [ { ""id"": 397910, ""type"": ""message"", ""date"": ""2018-02-21T10:27:59"", ""edited"": ""1970-01-01T01:00:00"", ""from"": ""Username"", ""from_id"": 39033284, ""text"": ""Some Text"" }, { ""id"": 397911, ""type"": ""message"", ""date"": ""2018-02-21T10:31:47"", ""edited"": ""1970-01-01T01:00:00"", ""from"": ""Username"", ""from_id"": 272964614, ""text"": [ ""Some Text "", { ""type"": ""mention"", ""text"": ""@school"" }, "" Some Text"" ] } ]"; List<JSONObject> jsonObjects = JsonConvert.DeserializeObject<List<JSONObject>>(json); Console.Read(); }
结果如下:
这篇关于反序列化具有多个数据类型的JSON文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!