在 C# 中,如何为具有多个嵌套数组的 JSON 对象建模?
Posted
技术标签:
【中文标题】在 C# 中,如何为具有多个嵌套数组的 JSON 对象建模?【英文标题】:In C#, how do I model a JSON object with multiple nested arrays? 【发布时间】:2014-10-04 20:53:33 【问题描述】:我正在从我正在连接的系统获取此 JSON 响应,并试图找出将其反序列化为 C# 对象的最佳方法。我目前正在使用RestSharp,这似乎很容易使用,但 JSON 的格式让我有点困惑。以下是它的格式:
[
"name": "Tickets:",
"schema": [
"dataType": "string", "colName": "First", "idx": 0,
"dataType": "string", "colName": "Second", "idx": 1,
"dataType": "string", "colName": "Name", "idx": 2
],
"data": [
["bill", "test", "joe"],
["bill2", "test2", "joe2"],
["bill3", "test3", "joe3"]
]
]
这是我当前的代码:
var url = "http://myUrl:10111";
var client = new RestClient BaseUrl = url ;
var request = new RestRequest Method = Method.GET, Resource = "/search?fmt=Json", RequestFormat = DataFormat.Json ;
request.AddHeader("accept", "application/json");
var response = client.Execute(request);
var wptResponse = new JsonDeserializer().Deserialize<TicketResults>(response);
return wptResponse;
但如上所述,我正在尝试找出对 TicketResults 对象进行建模以支持反序列化上述消息的正确方法。
理想情况下,我想要这样的东西:
public class TicketResults
public List<Ticket> Tickets get;set;
public class Ticket
public string First get;set;
public string Second get;set;
public string Name get;set;
在上面的示例中,Tickets 集合中将获得三个条目。
此外,上述 JSON 格式是否正常,因为我从未见过将其分解为单独的架构和数据部分(我可以看到它在哪里可以节省一些空间,但在这种情况下,消息不是那么大)
【问题讨论】:
查看 newtonsoft 库以将 json 反序列化为对象。也可以在类中的属性上方使用数据注解来映射到json属性。 问题更多是关于这个时髦的模式(相对于 RestSharp 的任何特定问题)。 是的,我之前使用过 newtonsoft 来处理一个时髦的方案,它是迄今为止最好的。只是将 OP 指向一个可能更简单的解决方案 由于生成的类中属性的数量和名称在编译时是未知的,您打算如何使用它们?即,假设当您运行代码时,REST 服务会为您提供名为“XYZ”的类的架构,该类具有“Foo”和“Bar”属性。但是为了实例化和使用这个类,你必须事先知道生成的类的名称,以及它的属性名称。 @Asad - 同意。 .我现在只是要忽略架构并假设硬编码字段(因为有人告诉我架构不会在不让我知道和更新的情况下更改 【参考方案1】:在 Visual Studio 2012 及更高版本中,您可以转到 Edit > Paste Special > Paste JSON as classes
。鉴于您从剪贴板粘贴的示例,它会生成以下代码。
public class Rootobject
public Class1[] Property1 get; set;
public class Class1
public string name get; set;
public Schema[] schema get; set;
public string[][] data get; set;
public class Schema
public string dataType get; set;
public string colName get; set;
public int idx get; set;
string json = File.ReadAllText("json.txt");
Rootobject root = new Rootobject();
root.Property1 = JsonConvert.DeserializeObject<Class1[]>(json);
【讨论】:
这不是 OP 想要反序列化的类。请看问题。 @Asad 刚刚对此进行了测试,它运行良好。将测试添加到我的答案中。这不仅解决了他当前 JSON 结构的问题,而且解决了将来尝试将 JSON 结构映射到类的所有问题。这就是我所说的给某人一根鱼竿而不是一条鱼。粘贴为 JSON 是一项很棒的功能,可以节省大量手动创建模型类的时间和精力。 对象上的命名已关闭(粘贴时自动生成的类的 bc),但它是相同的(我只是在我的回答中解决了对RootObject
的需求)。此外,粘贴 JSON 的 +1 - 不知道!
真棒没看到这节省了我很多时间谢谢!
这很棒。谢谢一百万!【参考方案2】:
我同意 json 格式相当……愚蠢。以下是如何为您的 dto 建模:
public class JsonDto
public string name get; set;
public Schema[] schema get; set;
public string[][] data get; set;
public class Schema
public string dataType get; set;
public string colName get; set;
public int idx get; set;
我能够让您的字符串(未更改)使用JSON.Net 反序列化,如下所示:
var jsonDto = JsonConvert.DeserializeObject<JsonDto[]>(json);
如果您仍有问题,请告诉我。
【讨论】:
当我使用上面的这个数据结构时,我得到以下错误:无法将“RestSharp.JsonArray”类型的对象转换为“System.Collections.Generic.IDictionary`2[System.String,System .Object]'. 我不得不返回 ListDeserializeObject<JsonDto[]>
- 特别是 JsonDto[]。这是 json 的愚蠢(是一个词吗?)的一部分——即使数组中只有一个对象,根元素也是一个数组。【参考方案3】:
您对返回的 JSON 的结构有任何控制权吗?这有点古怪。由于某种原因,字段名称和数据被分离出来。如果格式更合理一点,例如:
[
"First": "bill",
"Second": "test",
"Name": "joe"
,
"First": "bill2",
"Second": "test2",
"Name": "joe2"
,
]
然后您可以将其序列化到您的 Ticket 类。但是,如果不修改 JSON 结构(我不建议您这样做),您要序列化到的 C# 类将必须与 JSON 结构匹配。
我想你可以想出一个中间类来保存你收到的 JSON 数据。然后您可以遍历这些对象并从中创建 Ticket 类的实例。至少这样你最终得到了一个你可以使用的数据结构。
【讨论】:
很遗憾,我无法控制格式以上是关于在 C# 中,如何为具有多个嵌套数组的 JSON 对象建模?的主要内容,如果未能解决你的问题,请参考以下文章
C# Object to Json to Xml,如何为数组项生成xml元素
如何为嵌套 JSON 中存在 JSON 列表的嵌套 JSON 创建模型?
如何为来自 SpringBoot 后端代码的嵌套 JSON 响应在 angular8(TypeScript) 或更高版本中定义模型类