使用 JSON.NET 将 JSON 数据反序列化到 C #

我对使用 C # 和 JSON 数据相对较新,正在寻求指导。我使用的是 C # 3.0。NET3.5 SP1和 JSON.NET 3.5 r6。

我有一个定义好的 C # 类,需要从一个 JSON 结构中填充它。然而,并非从 Web 服务中检索到的条目的每个 JSON 结构都包含在 C # 类中定义的所有可能的属性。

我一直在做似乎是错误的,艰难的方法,只是从 JObject 中一个接一个地挑出每个值,然后将字符串转换成所需的类属性。

JsonSerializer serializer = new JsonSerializer();
var o = (JObject)serializer.Deserialize(myjsondata);


MyAccount.EmployeeID = (string)o["employeeid"][0];

将 JSON 结构反序列化为 C # 类并处理来自 JSON 源的可能丢失的数据的最佳方法是什么?

我的类被定义为:

  public class MyAccount
{


[JsonProperty(PropertyName = "username")]
public string UserID { get; set; }


[JsonProperty(PropertyName = "givenname")]
public string GivenName { get; set; }


[JsonProperty(PropertyName = "sn")]
public string Surname { get; set; }


[JsonProperty(PropertyName = "passwordexpired")]
public DateTime PasswordExpire { get; set; }


[JsonProperty(PropertyName = "primaryaffiliation")]
public string PrimaryAffiliation { get; set; }


[JsonProperty(PropertyName = "affiliation")]
public string[] Affiliation { get; set; }


[JsonProperty(PropertyName = "affiliationstatus")]
public string AffiliationStatus { get; set; }


[JsonProperty(PropertyName = "affiliationmodifytimestamp")]
public DateTime AffiliationLastModified { get; set; }


[JsonProperty(PropertyName = "employeeid")]
public string EmployeeID { get; set; }


[JsonProperty(PropertyName = "accountstatus")]
public string AccountStatus { get; set; }


[JsonProperty(PropertyName = "accountstatusexpiration")]
public DateTime AccountStatusExpiration { get; set; }


[JsonProperty(PropertyName = "accountstatusexpmaxdate")]
public DateTime AccountStatusExpirationMaxDate { get; set; }


[JsonProperty(PropertyName = "accountstatusmodifytimestamp")]
public DateTime AccountStatusModified { get; set; }


[JsonProperty(PropertyName = "accountstatusexpnotice")]
public string AccountStatusExpNotice { get; set; }


[JsonProperty(PropertyName = "accountstatusmodifiedby")]
public Dictionary<DateTime, string> AccountStatusModifiedBy { get; set; }


[JsonProperty(PropertyName = "entrycreatedate")]
public DateTime EntryCreatedate { get; set; }


[JsonProperty(PropertyName = "entrydeactivationdate")]
public DateTime EntryDeactivationDate { get; set; }


}

要解析的 JSON 示例是:

{
"givenname": [
"Robert"
],
"passwordexpired": "20091031041550Z",
"accountstatus": [
"active"
],
"accountstatusexpiration": [
"20100612000000Z"
],
"accountstatusexpmaxdate": [
"20110410000000Z"
],
"accountstatusmodifiedby": {
"20100214173242Z": "tdecker",
"20100304003242Z": "jsmith",
"20100324103242Z": "jsmith",
"20100325000005Z": "rjones",
"20100326210634Z": "jsmith",
"20100326211130Z": "jsmith"
},
"accountstatusmodifytimestamp": [
"20100312001213Z"
],
"affiliation": [
"Employee",
"Contractor",
"Staff"
],
"affiliationmodifytimestamp": [
"20100312001213Z"
],
"affiliationstatus": [
"detached"
],
"entrycreatedate": [
"20000922072747Z"
],
"username": [
"rjohnson"
],
"primaryaffiliation": [
"Staff"
],
"employeeid": [
"999777666"
],
"sn": [
"Johnson"
]
}
376751 次浏览

您尝试过使用通用的 SerializeObject 方法吗?

JsonConvert.DeserializeObject<MyAccount>(myjsondata);

JSON 数据中任何丢失的字段都应该保持为 NULL。

更新:

如果 JSON 字符串是一个数组,请尝试这样做:

var jarray = JsonConvert.DeserializeObject<List<MyAccount>>(myjsondata);

那么 jarray应该是 List<MyAccount>

另一个更新:

您得到的异常与对象数组不一致-我认为序列化程序与 Dictionary 类型的 accountstatusmodifiedby属性有问题。

尝试从序列化中排除 accountstatusmodifiedby属性,看看是否有帮助。如果是这样,您可能需要以不同的方式表示该属性。

文件: 用 JSON.NET 序列化和反序列化 JSON

你可使用:

JsonConvert.PopulateObject(json, obj);

Here: json是 json 字符串,obj是目标对象

注意: PopulateObject()不会删除 obj 的列表数据,在 Populate()之后,obj's列表成员将包含其原始数据和来自 json 字符串的数据

使用

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

JSON 2 C # 上创建类


Json.NET 文档: 用 JSON.NET 对 JSON 进行序列化和反序列化

假设您的示例数据是正确的,那么您的给定名称以及括号中的其他条目都是 JS 中的数组... ... 您将希望对这些数据类型使用 List。列表中的 Accountstatusexpmaxdate... ... 我认为您的示例中的日期格式不正确,因此不确定您的示例中还有什么不正确的地方。

这是一篇老文章,但是想记录下这些问题。

您可以尝试在线检查一些类生成器以获得更多信息。然而,我相信其中一些答案是有用的。这是我的方法,可能有用。

下面的代码是基于动态方法编写的。

dynObj = (JArray) JsonConvert.DeserializeObject(nvm);


foreach(JObject item in dynObj) {
foreach(JObject trend in item["trends"]) {
Console.WriteLine("{0}-{1}-{2}", trend["query"], trend["name"], trend["url"]);
}
}

这段代码基本上允许您访问 Json 字符串中包含的成员。只是不需要课程的另一种方式。querytrendurl是 Json 字符串中包含的对象。

你也可以使用 本网站。不要100% 相信这些类,但是你会明白的。

基于 bbant 的答案,这是我从远程 URL 反序列化 JSON 的完整解决方案。

using Newtonsoft.Json;
using System.Net.Http;


namespace Base
{
public class ApiConsumer<T>
{
public T data;
private string url;


public CalendarApiConsumer(string url)
{
this.url = url;
this.data = getItems();
}


private T getItems()
{
T result = default(T);
HttpClient client = new HttpClient();


// This allows for debugging possible JSON issues
var settings = new JsonSerializerSettings
{
Error = (sender, args) =>
{
if (System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break();
}
}
};


using (HttpResponseMessage response = client.GetAsync(this.url).Result)
{
if (response.IsSuccessStatusCode)
{
result = JsonConvert.DeserializeObject<T>(response.Content.ReadAsStringAsync().Result, settings);
}
}
return result;
}
}
}

用法如下:

ApiConsumer<FeedResult> feed = new ApiConsumer<FeedResult>("http://example.info/feeds/feeds.aspx?alt=json-in-script");

其中 FeedResult是使用 类生成器生成的类

下面是我使用的设置的屏幕截图,允许使用 网上版本无法解释的奇怪的属性名。

Xamasoft JSON Class Generator

我发现我没有正确地构建我的对象。我使用 http://json2csharp.com/从 JSON 生成对象类。一旦我有了正确的项目,我就可以毫无问题地施放。诺比特,菜鸟的错误。如果你也有同样的问题,我想我应该加上它。