0

我在解析来自 GraphQL 的 json 响应时遇到问题。问题是阵列将在一半时间内返回更多阵列。我的代码正在失控且丑陋。

Json 文件(修剪了一下。它可以是 20+ 数据数组)

{
  "activity_logs": [
    {
      "data": "{\"board_id\":2165785546,\"group_id\":\"new_group2051\",\"is_top_group\":false,\"pulse_id\":2165787062,\"pulse_name\":\"Tyler\",\"column_id\":\"email_address\",\"column_type\":\"email\",\"column_title\":\"Email Address\",\"value\":{\"column_settings\":{\"includePulseInSubject\":true,\"ccPulse\":true,\"bccList\":\"\"}},\"previous_value\":{\"email\":\"tyler@email.com\",\"text\":\"tyler@email.com\",\"changed_at\":\"2022-02-15T21:18:48.297Z\",\"column_settings\":{\"includePulseInSubject\":true,\"ccPulse\":true,\"bccList\":\"\"}},\"is_column_with_hide_permissions\":false,\"previous_textual_value\":\"tyler@email.com\"}"
    },
    {
      "data": "{\"board_id\":2165785546,\"group_id\":\"new_group2051\",\"is_top_group\":false,\"pulse_id\":216578711,\"pulse_name\":\"Nicholas \",\"column_id\":\"email_address\",\"column_type\":\"email\",\"column_title\":\"Email Address\",\"value\":{\"column_settings\":{\"includePulseInSubject\":true,\"ccPulse\":true,\"bccList\":\"\"}},\"previous_value\":{\"email\":\"nicholas@email.com\",\"text\":\"nicholas@email.com\",\"changed_at\":\"2022-02-16T04:44:52.046Z\",\"column_settings\":{\"includePulseInSubject\":true,\"ccPulse\":true,\"bccList\":\"\"}},\"is_column_with_hide_permissions\":false,\"previous_textual_value\":\"nicholas@email.com\"}"
    },
    {
      "data": "{\"board_id\":2165785546,\"group_id\":\"new_group2051\",\"is_top_group\":false,\"pulse_id\":216578711,\"pulse_name\":\"Nicholas \",\"column_id\":\"batch_5\",\"column_type\":\"text\",\"column_title\":\"Batch #\",\"value\":{\"value\":\"75\"},\"previous_value\":{\"value\":\"74\"},\"is_column_with_hide_permissions\":false}"
    },
    {
      "data": "{\"board_id\":2165785546,\"group_id\":\"new_group2051\",\"pulse_id\":216578711,\"is_top_group\":false,\"value\":{\"name\":\"Nicholas \"},\"previous_value\":{\"name\":\"Nicholas \"},\"column_type\":\"name\",\"column_title\":\"Name\"}"
    }
  ]
}

放弃制作后的随机“让它工作”尝试是基于类的列表。IContainers 中的 IContainers 变得非常复杂。

var responseData = JObject.Parse(responseText).SelectToken("data").SelectToken("boards").SelectToken("activity_logs");
dynamic updatedRecords = JsonConvert.DeserializeObject(responseData.ToString());

foreach (var record in updatedRecords)
{
List<Dictionary<string, string>> records = new List<Dictionary<string, string>>();
Dictionary<string, string> fields = new Dictionary<string, string>();
dynamic updates = JsonConvert.DeserializeObject(JObject.Parse(record.ToString()).SelectToken("data").ToString());
foreach(var update in updates)
{
    switch (update.Name.ToString())
    {
        case "column_id":
            fields.Add(update.Name.ToString(), update.Value.ToString());
            break;
        case "pulse_name":
            fields.Add(update.Name.ToString(), update.Value.ToString());
            break;
        case "value":
            dynamic values = JsonConvert.DeserializeObject(JObject.Parse(update.Value.ToString()));
            if (update.Name.ToString().Contains("column_settings"))
            {
                foreach (var value in values)
                {
                    dynamic columns = JsonConvert.DeserializeObject(JObject.Parse(value.Value.ToString()));
                    foreach(var column in columns)
                    {
                        fields.Add($"Value_{column.Name.ToString()}", column.Value.ToString());
                    }
                                                
                }
            }
            else
            {
                foreach (var value in values)
                {
                    fields.Add($"Value_{value.Name.ToString()}", value.Value.ToString());
                }
            }
                                        
            break;
        case "previous_value":
            dynamic prevValues = JsonConvert.DeserializeObject(JObject.Parse(update.Value.ToString()));
            foreach (var prevalue in prevValues)
            {
                fields.Add($"Prevalue_{prevalue.Name.ToString()}", prevalue.Value.ToString());
            }
            break;
        case "previous_textual_value":
            fields.Add(update.Name.ToString(), update.Value.ToString());
            break;
    }
}
if (fields.Count > 0)
{
    records.Add(fields);
    fields.Clear();
}
}

当我到达时我的错误:

dynamic values = JsonConvert.DeserializeObject(JObject.Parse(update.Value.ToString()));
-       $exception  {"The best overloaded method match for 'Newtonsoft.Json.JsonConvert.DeserializeObject(string)' has some invalid arguments"} Microsoft.CSharp.RuntimeBinder.RuntimeBinderException

解决方案是一个很大的帮助,并导致了我的回答。问题是 activity_logs 数据中带有转义字符,因此字符串包含 \\"。我必须使用 Replace("\\", "") 和 Replace("\"{", "{" 格式化数据部分) 和 Replace("}\""), "}")。这使得字符串可以作为 Json 文件读取。

4

2 回答 2

2

您必须传入一个字符串DeserializeObject而不是 JSON 对象。

另一种方法是将您的 JSON 映射到 POCO 类型,如下所示,简单的方法是在 Visual Studio 上(复制您的 JSON 内容,在 Visual Studio 上创建一个新的空类 -> 编辑 -> 过去的特殊 -> 将 JSON 粘贴为类)

public class LogsRoot
{
    public Activity_Logs[] activity_logs { get; set; }
}

public class Activity_Logs
{
    public string data { get; set; }
}

public class DataRoot
{
    public long board_id { get; set; }
    public string group_id { get; set; }
    public bool is_top_group { get; set; }
    public long pulse_id { get; set; }
    public string pulse_name { get; set; }
    public string column_id { get; set; }
    public string column_type { get; set; }
    public string column_title { get; set; }
    public Value value { get; set; }
    public Previous_Value previous_value { get; set; }
    public bool is_column_with_hide_permissions { get; set; }
    public string previous_textual_value { get; set; }
}

public class Value
{
    public Column_Settings column_settings { get; set; }
}

public class Column_Settings
{
    public bool includePulseInSubject { get; set; }
    public bool ccPulse { get; set; }
    public string bccList { get; set; }
}

public class Previous_Value
{
    public string email { get; set; }
    public string text { get; set; }
    public DateTime changed_at { get; set; }
    public Column_Settings1 column_settings { get; set; }
}

public class Column_Settings1
{
    public bool includePulseInSubject { get; set; }
    public bool ccPulse { get; set; }
    public string bccList { get; set; }
}

然后加载 JSON 并进行如下操作,

var json = File.ReadAllText("data.json");
var rootLogs = JsonConvert.DeserializeObject<LogsRoot>(json);

Dictionary<string, string> fields = new Dictionary<string, string>();

foreach (var logJson in rootLogs.activity_logs)
{
    var log = JsonConvert.DeserializeObject<DataRoot>(logJson.data);
    fields.Add(log.column_id, log.value.column_settings.bccList + log.value.column_settings.ccPulse);
    fields.Add(log.pulse_name, log.value.column_settings.bccList + log.value.column_settings.ccPulse);
    fields.Add(log.previous_value.email, log.value.column_settings.bccList + log.value.column_settings.ccPulse);
    fields.Add(log.previous_textual_value, log.value.column_settings.bccList + log.value.column_settings.ccPulse);
}
于 2022-02-24T02:57:00.320 回答
1

这可能无法解决您的所有问题,但对于您遇到的特定异常,这是因为您试图反序列化 JObject 而不是字符串。

可能你只是想要:

dynamic values = JsonConvert.DeserializeObject(update.Value.ToString());
于 2022-02-24T02:48:10.637 回答