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

143 c# json json.net deserialization

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

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

我一直在做看似错误的,艰难的方法,只是从JObject中逐个挑选每个值,并将字符串转换为所需的类属性.

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

MyAccount.EmployeeID = (string)o["employeeid"][0];
Run Code Online (Sandbox Code Playgroud)

将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; }

  }
Run Code Online (Sandbox Code Playgroud)

要解析的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"
    ]
}
Run Code Online (Sandbox Code Playgroud)

w.d*_*onk 274

使用 __CODE__

JSON 2 C#上创建类


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

  • Visual Studio还在"编辑 - 粘贴特殊"菜单中具有"粘贴JSON作为类"选项. (32认同)

Dav*_*sky 77

您是否尝试过使用通用的DeserializeObject方法?

JsonConvert.DeserializeObject<MyAccount>(myjsondata);
Run Code Online (Sandbox Code Playgroud)

JSON数据中任何缺少的字段都应该保留为NULL.

更新:

如果JSON字符串是数组,请尝试以下操作:

var jarray = JsonConvert.DeserializeObject<List<MyAccount>>(myjsondata);
Run Code Online (Sandbox Code Playgroud)

jarray应该是一个List<MyAccount>.

另一个更新:

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

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

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


bio*_*tal 49

答案转载自/sf/answers/750268991/

您可以使用C#dynamic类型来简化操作.这种技术也使得重新分解更简单,因为它不依赖于魔术字符串.

JSON

json下面的字符串是来自http api调用的简单响应,它定义了两个属性:IdName.

{"Id": 1, "Name": "biofractal"}
Run Code Online (Sandbox Code Playgroud)

C#

用于JsonConvert.DeserializeObject<dynamic>()将此字符串反序列化为动态类型,然后以通常的方式访问其属性.

var results = JsonConvert.DeserializeObject<dynamic>(json);
var id = results.Id;
var name= results.Name;
Run Code Online (Sandbox Code Playgroud)

注意:NewtonSoft程序集的NuGet链接是http://nuget.org/packages/newtonsoft.json.不要忘记添加:using Newtonsoft.Json;访问这些类.

  • 喜欢<dynamic>的使用.但是,我必须这样做才能使它工作:结果["Id"].值和结果["名称"].值 (7认同)
  • 你仍然有'魔术弦',他们现在只是被动态隐藏了! (4认同)

小智 8

您可以使用:

JsonConvert.PopulateObject(json, obj);
Run Code Online (Sandbox Code Playgroud)

这里:json是json字符串,obj是目标对象.见:例子

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

  • 它是PopulateObject - Populate不在对象模型中. (2认同)