gpt4 book ai didi

c# - 访问 json 文件中的子字段

转载 作者:太空宇宙 更新时间:2023-11-03 19:59:04 25 4
gpt4 key购买 nike

假设我有一个具有以下结构的 JSON 文件。我如何访问元数据字段中的属性名称。

{
"mappings": {
"basedoc_12kja": {
"properties": {
"created": {
"type": "date",
"format": "dateOptionalTime"
},
"customerID": {
"type": "string"
},
"deleted": {
"type": "boolean"
},
"documentID": {
"type": "string"
},
"id": {
"type": "string"
},
"metadata": {
"properties": {
"Cert": {
"type": "string"
},
"Exp_date": {
"format": "dateOptionalTime"
},
}
}
}
}
}
}

Mappings是一个文档数组,mappings的每个子字段都有不同的代码。我想获取每个文档的元数据字段,找出它们之间共有哪些元数据字段。

我无法实例化此文档。

var response = esReader.GetIndicesMapping();

foreach (var mapping in response.Response.Values)
{
// Parse JSON into dynamic object, convenient!
dynamic results = JObject.Parse(mapping);

List<DocumentType> deserializedObject = JsonConvert.DeserializeObject<List<DocumentType>>(mapping);

}

异常

{"Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[DocumentType]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\r\nPath 'mappings', line 2, position 14."}

期望的结果是获取CertExp_date字段的名称

编辑

public class DocumentType
{

public string Id { set { DocumentID = value; } get { return DocumentID; } }

public string DocumentID { set; get; }

public DateTime Created { set; get; }
.
.
.
public Dictionary<string, object> Metadata { set; get; }


}

最佳答案

这里的问题是你的数据结构与 JSON 不匹配:

  1. JSON 中没有数组。因此,您无法将其反序列化为 C# 列表。
  2. “DocumentType”类与 JSON 完全不匹配。该类具有 Created、CustomerID 和 Deleted 属性,它们类似于 DateTime 和字符串。但是 JSON 没有 DateTime 或字符串。它们是具有名为“类型”和“格式”的子属性的对象。属性“元数据”不是字典:它是一个对象,具有一个名为“properties”的属性,该属性可能应该是一个字典。
  3. 大小写不符。
  4. 不要对 Id 和 DocumentId 做那种奇怪的事情。该类应与 JSON 完全匹配且字面意思。没有隐藏在属性中的业务逻辑。
  5. 根对象有一个名为“映射”的属性,因此您需要在获取文档之前向下钻取。
  6. 成功获取文档后,您将需要深入到名为“properties”的属性以找到您感兴趣的字段。

我怀疑可能有多个文档,并且“映射”属性包含这些文档的列表,其中属性名称是动态的并且对应于文档的名称。处理这个问题是完全合理的,但不使用反序列化 + 列表方法。

我在这里看到 3 种方法:

  1. 修复 JSON。不确定您的情况是否可行。如果是这样,首先让映射包含一个数组,而不是让每个文档成为一个以文档名称命名的属性。
  2. 修复反序列化代码以匹配 JSON 文档。 json2csharp 做得很好所以从它开始。它只是不知道“映射”实际上是一个字典,而不仅仅是具有名为“basedoc12_kja”的属性的东西。
  3. 根本不要反序列化它。只需查询元数据。看看http://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm其中展示了使用 JObject 属性和 LINQ 查询 JSON 的几种方法。

选项 1

如果你走那条路,稍微清理过的 JSON 的例子:

{
"mappings": [
{
"name"" : "basedoc_12kja",
"properties": {
""created": "20150522",
etc.
},

注意“映射”是一个数组,名称成为文档的属性。现在您可以创建一个 List<> 或使用 JArray。更好的办法是去掉顶部未使用的东西,像这样:

[
{
"name" : "basedoc_12kja",
"properties": {
"created"": "20150522",
etc.
},
]

现在它只是一个完全没有“映射”的数组。

** 选项 2 **这是将通过反序列化执行此操作的代码。有两部分。第一步是使用 json2charp 生成的内容。我将在此处包含它以供引用:

public class Created
{
public string type { get; set; }
public string format { get; set; }
}

public class CustomerID
{
public string type { get; set; }
}

public class Deleted
{
public string type { get; set; }
}

public class DocumentID
{
public string type { get; set; }
}

public class Id
{
public string type { get; set; }
}

public class Cert
{
public string type { get; set; }
}

public class ExpDate
{
public string format { get; set; }
}

public class Properties2
{
public Cert Cert { get; set; }
public ExpDate Exp_date { get; set; }
}

public class Metadata
{
public Properties2 properties { get; set; }
}

public class Properties
{
public Created created { get; set; }
public CustomerID customerID { get; set; }
public Deleted deleted { get; set; }
public DocumentID documentID { get; set; }
public Id id { get; set; }
public Metadata metadata { get; set; }
}

public class Basedoc12kja
{
public Properties properties { get; set; }
}

public class Mappings
{
public Basedoc12kja basedoc_12kja { get; set; }
}

public class RootObject
{
public Mappings mappings { get; set; }
}

然后,将 Basedoc12kja 重命名为 DocumentType,并将 RootObject 更改为包含字典。你得到这个:

public class DocumentType
{
public Properties properties { get; set; }
}

public class RootObject
{
public Dictionary<string, DocumentType> mappings { get; set; }
}

如果您想要获取 Cert 和 Exp_date 以外的属性,请将元数据更改为:

public class Metadata
{
public Dictionary<string,object> properties { get; set; }
}

现在可以反序列化您的文档了:

JObject results = JObject.Parse(mapping);
RootObject ro = results.ToObject<RootObject>()

您可以枚举映射并获取属性。由于 JSON 结构,它们仍然很困惑,但您至少可以到达那里。

希望对您有所帮助!

关于c# - 访问 json 文件中的子字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30401567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com