【问题标题】:Looping through generic object properties循环遍历通用对象属性
【发布时间】:2016-09-09 22:52:30
【问题描述】:

我有一个 JSON 字符串存储在这样的数据库中:

{
    "Error": "Lol",
    "ErrorDate": "2016-05-13T10:43:27.6365795Z",
    "Application": "Business",
    "UserName": "Josh",
    "TraceSession": "moo"
}

表中每个项目的 JSON 字符串都不同。 在我的应用程序中,我想将其反序列化为一个对象,但由于 JSON 始终不同,我无法创建模型。

目前我有这个:

var jObject = JsonConvert.DeserializeObject(FieldNames);

我认为这会起作用,但现在我需要遍历属性以获取 key 名称和值。我试过这个:

// For each property in our oject
foreach (var key in jObject.GetProperties())
{

    // Create a list
    var list = new List<string>();
    list.Add(key.GetValue());            

    // Add our substitution
    email.AddSubstitution($"--{ key.ToUpper() }--", list);
}

但它失败了,因为

“object”不包含“GetProperties”的定义

有谁知道我该如何解决这个问题?

【问题讨论】:

  • 你不需要先反序列化到一个对象类型
  • 为什么不创建一个类来反序列化呢?然后你有一个很好的简单对象可以使用
  • 正如我所说,每行的 JSON 都会发生变化

标签: c# json json.net


【解决方案1】:
var jsonData = "{\"Error\": \"Lol\",\"ErrorDate\": \"2016-05-13T10:43:27.6365795Z\",\"Application\": \"Business\",\"UserName\": \"Josh\",\"TraceSession\": \"moo\"}";
var jObj = JToken.Parse(jsonData);
foreach (JProperty property in jObj.Children())
{
    Console.WriteLine(property.Name);
    Console.WriteLine(property.Value);
}

【讨论】:

    【解决方案2】:

    如果我正确理解您的问题,您没有反序列化为具体对象,因为您的字段/键不是 certian?

    在这种情况下,我发现将我的 Json 对象视为字符串/对象对的字典,然后从那里使用它很方便。我倾向于使用 object 作为我的值,因为我们的 Json 可以容纳各种各样的东西。话虽如此,如果您确定您的值只是字符串,那么您可以只使用字符串/字符串对并节省一些转换。这可以通过以下位轻松实现:

    帮助我们的扩展方法: (如果您的 Json 不是真正的 Json,这将失败,因此如果您需要,请将其包装在 try/catch 中。)

    public static T Deserialize<T>(this string json)
    {
        return string.IsNullOrWhiteSpace(json) ? default(T) : JsonConvert.DeserializeObject<T>(json);
    }
    

    其次是它的用法: (注意,静态调用它也会保护你免受空值的影响,所以你可以随意使用它。)

    var dict = yourJsonString.Deserialize<Dictionary<string, object>>();
    

    现在回答您最初的问题,我们可以这样做:

    dict.ToList().ForEach(pair =>
    {
        //Do your work with each pair here.
    });
    

    我的一些同事讨厌像这样使用 Linq 进行迭代,所以我们也可以这样做:

    foreach (var pair in dict)
    {
        //Work with each pair here.
    }
    

    如果您仍想查看正在使用的键的列表:

    dict.Keys;
    

    【讨论】:

      【解决方案3】:

      根据您的要求,您可以使用动态关键字:

      dynamic result = JObject.Parse("{...}");
      

      然后你可以访问任何类似的属性:

      if (result.MyProperty != null)
      {
      }
      

      您还可以循环遍历动态对象。

      由于 json 的性质,您不会有任何静态类型的对象,因此 dynamic 关键字似乎很合适。

      【讨论】:

        【解决方案4】:

        JObject 本质上是一个字典。您可以像这样遍历键/值:

        class Program
        {
            static void Main(string[] args)
            {
                const string json = "{ " +
                    "\"Error\": \"Lol\", " +
                    "\"ErrorDate\": \"2016-05-13T10:43:27.6365795Z\", " +
                    "\"Application\": \"Business\", " +
                    "\"UserName\": \"Josh\", " +
                    "\"TraceSession\": \"moo\" " +
                " }";
        
                var jobj = JObject.Parse(json);
        
                foreach (var prop in jobj)
                {
                    Console.WriteLine("Key: {0}, Value: {1}", prop.Key, prop.Value);
                }
            }
        }
        

        【讨论】:

          【解决方案5】:

          您只能从类型中获取属性,而不能从实例中获取。

          你应该打电话给:

          foreach (var key in jObject.GetType().GetProperties())
          {
          }
          

          附带说明,在反序列化 json 时,您可能应该使用静态类型

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-01-26
            • 2021-11-20
            • 2014-12-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多