C#JSON中的解包属性 [英] Unwrapped property in C# JSON

查看:52
本文介绍了C#JSON中的解包属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要反序列化此JSON:

{ "user_id": 0, "resource_id": 0, "resource_name": "file.xml" ...}

致此类:

public class Resource 
{
    public ResourceId ResourceId { get; set; }
    public string ResourceName { get; set; }
    ... 
}

public class ResourceId 
{
    public int UserId { get; set; }
    public int ResourceId { get; set; }
}

我需要反序列化程序创建一个新的ResourceId对象来存储"resource_id"和"user_id"的值。此外,我还需要将对象序列化。这可能吗?

我正在使用JSON.net反序列化程序/序列化程序。

推荐答案

首先,您的ResourceId类甚至不会编译,因为member names cannot be the same as their enclosing type。相反,您必须执行如下操作:

public class ResourceId 
{
    public int UserId { get; set; }
    public int Id { get; set; }
}
您的下一个问题是包含的类ResourceId的属性作为容器类Resource的属性出现在JSON中。在不更改数据模型的情况下处理此的一种方法是将它们序列化为容器类上的私有属性,该属性代理底层ResourceId的属性。这可以通过使用data contract attributes注释Resource来完成,如下所示:

[DataContract]
public class Resource 
{
    [IgnoreDataMember]
    public ResourceId ResourceId { get; set; }

    [DataMember(Name="user_id")]
    private int? user_id {
        get
        {
            return ResourceId == null ? (int ?)null : ResourceId.UserId;
        }
        set
        {
            if (value == null)
            {
                ResourceId = null;
            }
            else
            {
                if (ResourceId == null)
                    ResourceId = new ResourceId();
                ResourceId.UserId = value.Value;
            }
        }
    }

    [DataMember(Name="resource_id")]
    private int? resource_id
    {
        get
        {
            return ResourceId == null ? (int?)null : ResourceId.Id;
        }
        set
        {
            if (value == null)
            {
                ResourceId = null;
            }
            else
            {
                if (ResourceId == null)
                    ResourceId = new ResourceId();
                ResourceId.Id = value.Value;
            }
        }
    }

    [DataMember(Name="resource_name")]
    public string ResourceName { get; set; }
}

或与Json.NET的[JsonIgnore] and [JsonProperty] serialization attributes类似:

public class Resource 
{
    [JsonIgnore]
    public ResourceId ResourceId { get; set; }

    [JsonProperty("user_id")]
    private int? user_id {
        get
        {
            return ResourceId == null ? (int ?)null : ResourceId.UserId;
        }
        set
        {
            if (value == null)
            {
                ResourceId = null;
            }
            else
            {
                if (ResourceId == null)
                    ResourceId = new ResourceId();
                ResourceId.UserId = value.Value;
            }
        }
    }

    [JsonProperty("resource_id")]
    private int? resource_id
    {
        get
        {
            return ResourceId == null ? (int?)null : ResourceId.Id;
        }
        set
        {
            if (value == null)
            {
                ResourceId = null;
            }
            else
            {
                if (ResourceId == null)
                    ResourceId = new ResourceId();
                ResourceId.Id = value.Value;
            }
        }
    }

    [JsonProperty("resource_name")]
    public string ResourceName { get; set; }
}

备注:

  • 属性应该是私有的,因为当null是可能的值时,单独更改它们确实没有意义。例如,执行以下操作:

    resource.user_id = null;
    resource.resource_id = 3;
    

    可能会产生意外结果。

  • 使用数据协定属性使类与数据协定序列化程序兼容,这可能很有用。

演示小提琴here用于数据合同属性,here用于Newtonsoft属性。

这篇关于C#JSON中的解包属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆