无法在 WPF 中将 JSON 数据与 Newtonsoft.Json 一起使用
Unable to use JSON data with Newtonsoft.Json in WPF
我正在从 office365 中检索数据 api。响应采用 JSON 格式。我想将 Id、DisplayName 等数据获取到变量中,但没有找到正确的方法。正在关注 this link。我是 API 和 JSON 的新手。也将感谢指向下面的最佳学习 links.Sample JSON 的指针,用于列出收件箱文件夹的子文件夹。
响应JSON数据。
{"@odata.context":"https://outlook.office365.com/api/v1.0/$metadata#Me/Folders('Inbox')/ChildFolders","value":
[
{"@odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user@demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmsdfsdfdDSFSDFDFDF=')",
"Id":"AAMkADBjMdfgdfgDFGDFGDFGdfGDFGDFGDFGGDzrACAAB4xqMmAAA=",
"DisplayName":"SampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":8,"TotalItemCount":94},
{"@odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user@demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEasdasdasdASDASDASDASDSADDASDASDAB4xqMnAAA=')",
"Id":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmOGZkNGRhZmIzNQAuAasdASDASDASDASEDASDASDxSEHjzrACAAB4xqMnAAA=",
"DisplayName":"AnotherSampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":21,"TotalItemCount":75}
]
}
C# 代码 用于解析 JSON 并查找所需数据。
HttpResponseMessage response = httpClient.SendAsync(request).Result;
if (!response.IsSuccessStatusCode)
throw new WebException(response.StatusCode.ToString() + ": " + response.ReasonPhrase);
string content = response.Content.ReadAsStringAsync().Result;
JObject jResult = JObject.Parse(content);
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
var folderName = results.Id;
var folderId = results.Name;
//Attempt two - [Not working - Throwing exception -
//Object reference not set to an instance of an object.]
var folderID = (string)jResult["odata.context"]["odata.id"][0]["Id"];
反序列化 JSON 的一种方法是为要处理的对象创建模型 类 并直接反序列化到它们中,例如。 JsonConvert.DeserializeObject<Folder>(content)
。当您与 Office365 API 交谈时,您会找到有关如何定义它们的文档和示例 here。
以您的文件夹响应为例,您的单个 Folder
模型可能如下所示:
public class Folder
{
[JsonProperty(PropertyName = "@odata.id")]
public string OdataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
注意 1:在您的示例中,您会收到包含 list 个文件夹的响应,因此必须相应地进行调整。
注 2:您可以使用 JsonProperty
定义 JSON property/key 和 C# 属性 之间的映射,如 @odata.id
.
所示
但是,您也可以使用 Outlook Client Library,这几乎不需要直接处理 JSON 数据(这似乎更可取,除非您有非常具体的理由来处理 JSON直接)。
首先为您的 json 对象创建一个 class
public class RootObject
{
[JsonProperty(PropertyName = "@odata.context")]
public string context { get; set; }
public List<Value> value { get; set; }
}
public class Value
{
[JsonProperty(PropertyName = "@odata.id")]
public string dataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
然后 Json 如果您使用的是 Newtonsoft Json,则将 Json 字符串转换为您的 RootObject,然后使用
反序列化
RootObject shortiee = JsonConvert.DeserializeObject<RootObject>("Your Json String");
private List<string> GetDisplayNames(JObject content)
{
var obj = Json.Parse(content);
var values = obj["value"].ToList();
var displayNames = new List<string>();
foreach (var value in values)
{
displayNames .Add(system["DisplayName"].ToString());
}
return displayNames;
}
例如,这将 return 名称,您可以为需要检索的每个值执行此操作。但是,这并不要求您在使用前 serialize/deserialize json 对象。它有效,但很可能不是最佳实践。
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
旁注:您的 JSON 数据中没有名为 "odata.error" 的键。所以你有效地调用了一些东西 return null.
我正在从 office365 中检索数据 api。响应采用 JSON 格式。我想将 Id、DisplayName 等数据获取到变量中,但没有找到正确的方法。正在关注 this link。我是 API 和 JSON 的新手。也将感谢指向下面的最佳学习 links.Sample JSON 的指针,用于列出收件箱文件夹的子文件夹。
响应JSON数据。
{"@odata.context":"https://outlook.office365.com/api/v1.0/$metadata#Me/Folders('Inbox')/ChildFolders","value":
[
{"@odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user@demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmsdfsdfdDSFSDFDFDF=')",
"Id":"AAMkADBjMdfgdfgDFGDFGDFGdfGDFGDFGDFGGDzrACAAB4xqMmAAA=",
"DisplayName":"SampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":8,"TotalItemCount":94},
{"@odata.id":"https://outlook.office365.com/api/v1.0/Users('sample.user@demosite.com')/Folders('AAMkADBjMGZiZGFlLTE4ZmEasdasdasdASDASDASDASDSADDASDASDAB4xqMnAAA=')",
"Id":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1iMjllLTJmOGZkNGRhZmIzNQAuAasdASDASDASDASEDASDASDxSEHjzrACAAB4xqMnAAA=",
"DisplayName":"AnotherSampleFolder","ParentFolderId":"AAMkADBjMGZiZGFlLTE4ZmEtNGRlOS1sdsDFSDFSDFSDFSDFSDFDFDFrACAAAAAAEMAAA=","ChildFolderCount":0,"UnreadItemCount":21,"TotalItemCount":75}
]
}
C# 代码 用于解析 JSON 并查找所需数据。
HttpResponseMessage response = httpClient.SendAsync(request).Result;
if (!response.IsSuccessStatusCode)
throw new WebException(response.StatusCode.ToString() + ": " + response.ReasonPhrase);
string content = response.Content.ReadAsStringAsync().Result;
JObject jResult = JObject.Parse(content);
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
var folderName = results.Id;
var folderId = results.Name;
//Attempt two - [Not working - Throwing exception -
//Object reference not set to an instance of an object.]
var folderID = (string)jResult["odata.context"]["odata.id"][0]["Id"];
反序列化 JSON 的一种方法是为要处理的对象创建模型 类 并直接反序列化到它们中,例如。 JsonConvert.DeserializeObject<Folder>(content)
。当您与 Office365 API 交谈时,您会找到有关如何定义它们的文档和示例 here。
以您的文件夹响应为例,您的单个 Folder
模型可能如下所示:
public class Folder
{
[JsonProperty(PropertyName = "@odata.id")]
public string OdataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
注意 1:在您的示例中,您会收到包含 list 个文件夹的响应,因此必须相应地进行调整。
注 2:您可以使用 JsonProperty
定义 JSON property/key 和 C# 属性 之间的映射,如 @odata.id
.
但是,您也可以使用 Outlook Client Library,这几乎不需要直接处理 JSON 数据(这似乎更可取,除非您有非常具体的理由来处理 JSON直接)。
首先为您的 json 对象创建一个 class
public class RootObject
{
[JsonProperty(PropertyName = "@odata.context")]
public string context { get; set; }
public List<Value> value { get; set; }
}
public class Value
{
[JsonProperty(PropertyName = "@odata.id")]
public string dataId { get; set; }
public string Id { get; set; }
public string DisplayName { get; set; }
public string ParentFolderId { get; set; }
public int ChildFolderCount { get; set; }
public int UnreadItemCount { get; set; }
public int TotalItemCount { get; set; }
}
然后 Json 如果您使用的是 Newtonsoft Json,则将 Json 字符串转换为您的 RootObject,然后使用
反序列化RootObject shortiee = JsonConvert.DeserializeObject<RootObject>("Your Json String");
private List<string> GetDisplayNames(JObject content)
{
var obj = Json.Parse(content);
var values = obj["value"].ToList();
var displayNames = new List<string>();
foreach (var value in values)
{
displayNames .Add(system["DisplayName"].ToString());
}
return displayNames;
}
例如,这将 return 名称,您可以为需要检索的每个值执行此操作。但是,这并不要求您在使用前 serialize/deserialize json 对象。它有效,但很可能不是最佳实践。
if (jResult["odata.error"] != null)
throw new Exception((string)jResult["odata.error"]["message"]["value"]);
//Attempt one - using dynamic [NOT WORKING - getting NULL values in the variables]
dynamic results = JsonConvert.DeserializeObject<dynamic>(content);
旁注:您的 JSON 数据中没有名为 "odata.error" 的键。所以你有效地调用了一些东西 return null.