如何动态反序列化Json String

如何动态反序列化Json String

问题描述:

我通过SSE Stream消费了调查数据,该数据使我每个人都以Survey X的这种格式逐行回答:

I have consume Survey data via SSE Stream that gives me each persons answers line by line with this format for Survey X:

{"data":["4482359","12526","5","5","","Yes, that is right","1"]}

我使用Streamreader

 Dim sr As StreamReader = New StreamReader(stream)
 Dim myList As List(Of String) = New List(Of String)

 While sr.Peek >= 0
     myList.Add(sr.ReadLine())
 End While

现在,我想反序列化字符串,以便将条目输入到可以访问的类的属性中(让我们将其称为tmpUserData).我已经尝试过使用Newtonsoft.Json:

Now I want to deserialize the strings so I get the entries into properties of a class (let us call it tmpUserData) that I can access. I have tried this using Newtonsoft.Json:

Dim tmpUserData As Object = JsonConvert.DeserializeObject(Of Object)(myList(i))

但查看tmpUserData的反序列化不会将条目拆分为

but looking into tmpUserData the deserialization does not split the entries as

(1) User1
  (1) "4482359"
  (2) "12526"
  (3) "5"
  (4) ""
...    
(2) User1
  (1) "5847895"
  (2) "33568"
  (3) "6"
  (4) "2"
...

但相反,它只是将所有内容都放在一个条目中

but instead it just put everything into one entry

(1) "4482359","12526","5","5","","Yes, that is right","1"

我不能只写一个类并将数据放入其中的原因

The reason why I cannot just write a class and put the data into it like

JsonConvert.DeserializeObject(myclass)(myList(i))

这是必须动态的,因为对于不同的调查,字符串的数量和结构是不同的.因此Survey Y可能看起来像:

is that this has to be dynamically since the number and structure of strings differs for different surveys. So Survey Y might looks like:

{"data":["Peter","Jackson","Albert Street","5","","1"]}

有人可以帮我得到我想要的东西吗,以便正确地反序列化每个参加者的条目? C#也欢迎提供解决方案.

Could anyone help me get what I am looking for so the entries of each Survery Particpant are properly deserialized? C# Solution is welcome as well.

假定这是流的内容:

{"data":["4482359","12526","5","5","","Yes, that is right","1"]}
{"data":["2223446","65432","3","3","","Nope, that's not right","0"]}
(...)

您可以使用List<class>反序列化这些行.像这样:

you can deserialize these lines using a List<class>. Something like this:

using System.IO;
using Newtonsoft.Json;

public class RootObject
{
    public List<string> data { get; set; }
}

可以通过两种简单的方法反序列化JSON流:

That JSON streaming can be deserialize in two simple ways:

  • 如果您真的不需要逐行解析流,请阅读流的结尾,然后使用 JsonSerializer 将读者的结果反序列化为您用作数据容器的类的实例:
  • If you don't really need to parse the stream line by line, read the stream to end, then use a JsonTextReader to read the resulting string and JsonSerializer to deserialize the reader's result into an instance of the class you're using as container for the data:

List<RootObject> dataObjects = new List<RootObject>();

using (StreamReader sr = new StreamReader(stream))
{
    var JSONObject = sr.ReadToEnd();
    var reader = new JsonTextReader(new StringReader(JSONObject)) { SupportMultipleContent = true };
    var serializer = new JsonSerializer();

    while (reader.Read()) {
        dataObjects.Add(serializer.Deserialize<RootObject>(reader));
    }
    reader.Close();
}

VB.Net版本:

Imports System.IO
Imports Newtonsoft.Json

Public Class RootObject
    Public Property MyData As List(Of String)
End Class

Dim dataObjects As New List(Of RootObject)()
Using sr As New StreamReader(stream)
    Dim JSONObject As String = sr.ReadToEnd()

    Dim reader = New JsonTextReader(New StringReader(JSONObject)) With {
        .SupportMultipleContent = True
    }
    Dim serializer = New JsonSerializer()
    While reader.Read()
        dataObjects.Add(serializer.Deserialize(Of RootObject)(reader))
    End While
    reader.Close()
End Using

  • 如果出于某些原因(此处未指定)而需要逐行解析流,则可以在第一行之前插入数组定界符[,在最后一行之后插入],用(逗号)分隔每行.现在,您可以使用 JsonConvert.DeserializeObject<Object>(JSON) 进行反序列化的功能数组.
    • If you need to parse the stream line by line for some reason not specified here, you could insert an array delimiter [ before the first line and ] after the last line, separating each line with a (comma). You have now a functional array that can be deserialized with JsonConvert.DeserializeObject<Object>(JSON)
    • 最终产品将如下所示:

[ {"data":["value1","value2","value3", (...)]},
  {"data":["value1","value2","value3", (...)]} ]

List<RootObject> dataObjects = new List<RootObject>();

using (StreamReader sr = new StreamReader(stream))
{
    var JSONObject = sr.ReadToEnd();
    dataObjects = JsonConvert.DeserializeObject<List<RootObject>>(JSONObject);
}

VB.Net版本:

Dim dataObjects As New List(Of RootObject)()

Using sr As New StreamReader(stream)
    Dim JSONObject As String = sr.ReadToEnd()
    dataObjects = JsonConvert.DeserializeObject(Of List(Of RootObject))(JSONObject)
End Using