C#解析从GraphQL-Monday.com返回的Json字符串



我在解析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内部的IContainer变得非常复杂。

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数据中带有转义符,因此字符串包含\\ quot;。我不得不用替换("\\","(和替换("\","{"(以及替换("}\"(,"}&"(。这使得字符串作为Json文件可读。

您必须将字符串传递给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);
}

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

也许你只是想要:

dynamic values = JsonConvert.DeserializeObject(update.Value.ToString());

最新更新