杰森不知道结构

时间:2016-03-07 17:05:10

标签: json parsing json.net

嘿,我需要一些帮助来循环遍历以下JSON字符串:

{
  "application_uid" : "3912d337-b797-4508-8c95-c76df8888ada",
  "formId" : "F_Form1",
  "recordCount" : 1,
  "items" :
    [
        {
    "lastModified" : "2015-12-11T20:07:25.774Z",
    "lastModifiedBy" :
      {
        "displayName" : "Anonymous Guest User",
        "email" : "",
        "login" : "Anonymous Guest User"
      },
    "created" : "2015-12-11T20:07:25.774Z",
    "createdBy" :
      {
        "displayName" : "Anonymous Guest User",
        "email" : "",
        "login" : "Anonymous Guest User"
      },
    "draft_ownerid" : "",
    "flowState" : "ST_End",
    "id" : 20,
    "uid" : "5928bb18-5b53-43f9-8831-baab042e1ca2",
    "F_ReceivedYorN" : "Y",
    "F_ContractNumber" : "5556420121",
    "F_FileNumber" : "0630250",
    "F_SubscriberLastName" : "JEFFERY",
    etc etc...

问题在于名称可以更改 F_ReceivedYorN F_ContractNumber F_FileNumber

我知道如何通过循环获取值,但只能定义对象的名称。无论 flowState id uid 值是什么,它们都将保持静态。

即使我不知道他们将被称为什么,我怎么能循环遍历每个名​​字?

更新

假设的解决方案没有帮助,因为它不像我上面的例子。的 REOPEN

1 个答案:

答案 0 :(得分:1)

您的JSON包含一个根对象,该对象包含"items"属性,该属性具有包含标准和变量属性的对象数组。您需要在不事先知道的情况下捕获每个项目中的所有属性名称和值。

您已标记了问题,因此我将在c#中回答。你有几个选择。

使用[JsonExtensionData]

通过将[JsonExtensionData]添加到自定义属性名称/值对的字典中,Json.NET支持将任意JSON属性反序列化和重新序列化为POCO:

public class Item
{
    public Item() { this.CustomFields = new Dictionary<string, JToken>(); }

    public string flowState { get; set; }
    public long id { get; set; }
    public Guid uid { get; set; }

    [JsonExtensionData]
    public IDictionary<string, JToken> CustomFields { get; private set; }
}

public class RootObject
{
    public RootObject() { this.items = new List<Item>(); }

    public Guid application_uid { get; set; }
    public string formId { get; set; }
    public int recordCount { get; set; }
    public List<Item> items { get; set; }
}

然后,您可以按如下方式遍历自定义属性的名称和值:

        var root = JsonConvert.DeserializeObject<RootObject>(json);

        foreach (var item in root.items)
        {
            Console.WriteLine(string.Format("Showing custom properties for Item id {0}, uid {1}, flowState {2}", item.id, item.uid, item.flowState));
            {
                foreach (var field in item.CustomFields)
                {
                    Console.WriteLine(string.Format("    Field: \"{0}\": Value: \"{1}\"", field.Key, field.Value.ToString(Formatting.None)));
                }
                Console.WriteLine("");
            }
        }

原型fiddle

使用ExpandoObject

Json.NET直接支持deserializing to ExpandoObject,因此您可以将此类用于您的项目:

public class RootObject
{
    public RootObject() { this.items = new List<ExpandoObject>(); }

    public Guid application_uid { get; set; }
    public string formId { get; set; }
    public int recordCount { get; set; }
    public List<ExpandoObject> items { get; set; }
}

然后做:

        var root = JsonConvert.DeserializeObject<RootObject>(json);

        foreach (var item in root.items)
        {
            Console.WriteLine(string.Format("Showing custom properties for Item id {0}, uid {1}, flowState \"{2}\":", 
                                            item.AsDynamic().id, item.AsDynamic().uid, item.AsDynamic().flowState));
            {
                foreach (var field in item.AsDictionary())
                {
                    if (field.Key == "id" || field.Key == "uid" || field.Key == "flowState")
                        continue;                       
                    Console.WriteLine(string.Format("  - Field: \"{0}\":\n    Value: {1}", field.Key, JsonConvert.SerializeObject(field.Value)));
                }
                Console.WriteLine("");
            }
        }

使用以下扩展方法:

public static class DictionaryExtensions
{
    public static IDictionary<TKey, TValue> AsDictionary<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
    {
        return dictionary;
    }
}

public static class DynamicExtensions
{
    public static dynamic AsDynamic(this IDynamicMetaObjectProvider obj)
    {
        return obj;
    }
}

原型fiddle

这消除了模型中对Json.NET的直接依赖性。但是,与第一个解决方案不同,ExpandoObject是密封的,因此无法进行子类化以添加标准的三个属性。