【问题标题】:Is it possible to serialize different property sets using DataContractJsonSerializer?是否可以使用 DataContractJsonSerializer 序列化不同的属性集?
【发布时间】:2012-08-17 13:20:23
【问题描述】:

我正在使用 WCF 和 JSON 构建一个(希望如此)RESTful 服务。

例如:

[DataContract]
public class Person
{
    // This member is serialized.
    [DataMember]
    internal string FullName;

    // This is serialized even though it is private.
    [DataMember]
    private int Age;

    // This is not serialized because the DataMemberAttribute 
    // has not been applied.
    private string MailingAddress;

    // This is not serialized, but the property is.
    private string telephoneNumberValue;

    [DataMember]
    public string TelephoneNumber
    {
        get { return telephoneNumberValue; }
        set { telephoneNumberValue = value; }
    }
}

我需要从 WCF 方法返回一个不带电话号码的 Person 对象(即仅带 FullName 和 Age),所以我想知道是否可以仅使用 Person 类和 WFC 方法的属性属性来实现它?

谢谢

【问题讨论】:

  • 我没有得到完整的上下文 - 如果你从 TelephoneNumer 属性中删除 DataMember 属性,它不会回答你的问题吗(只返回一个带有 FullName 和 Age 的 Person 对象)?
  • 嗯,你说得对——我不清楚。我还需要现有的设置,以及根据服务方法决定以哪种方式序列化事物的能力。

标签: json wcf rest


【解决方案1】:

或者,您可以使用 [DataMember(EmitDefaultValue=false)] 并将您不想序列化的字段设置为 null 或根本不初始化

例如

[DataContract]
public class Person
{
    // This member is serialized.
    [DataMember]
    internal string FullName;

    [DataMember( EmitDefaultValue=false)]
    public string TelephoneNumber
    {
        get { return telephoneNumberValue; }
        set { telephoneNumberValue = value; }
    }
}

那么您可能有 2 种方法以 2 种不同的方式加载\创建 Person

public Person LoadWithPhone() 
    {
        return new Person() { FullName = "Name", TelephoneNumber = "123456" };
    }

 public Person LoadWithoutPhone() 
    {
        return new Person() { FullName = "Name" }; //TelephoneNumber is null
    }

那么当序列化第二种方法创建的人时,TelephoneNumber 不会被序列化 这在从数据库加载对象时可能很有用,您可以有几种方法来加载不同的列,或者有一种方法可以动态构建查询并仅使用请求的字段初始化对象。

【讨论】:

    【解决方案2】:

    简单的答案是您不能这样做,但这里有一个示例,说明您无需大量工作即可实现相同目标。

    您需要有两个Person 类,一个具有PhoneNumberDataMember 属性,另一个没有。最好的方法可能是从主 Person 类创建两个子类

    [DataContract]
    public class PersonWithoutPhone
    {
        private Person _p;
    
        public PersonWithoutPhone(Person p)
        {
            _p = p;
        }
    
        [DataMember]
        internal string FullName
        {
            get { return _p.FullName; }
        }
    
        [DataMember]
        private int Age
        {
            get { return _p.Age; }
        }
    
        public string TelephoneNumber
        {
            get { return _p.TelephonNumber; }
        }
    }
    
    [DataContract]
    public class PersonWithPhone
    {
        private Person _p;
    
        public PersonWithoutPhone(Person p)
        {
            _p = p;
        }
    
        [DataMember]
        internal string FullName
        {
            get { return _p.FullName; }
        }
    
        [DataMember]
        private int Age
        {
            get { return _p.Age; }
        }
    
        [DataMember]
        public string TelephoneNumber
        {
            get { return _p.TelephonNumber; }
        }
    }
    

    【讨论】:

    • 那么,答案是否定的?
    • 是的,简单的答案是否定的,很抱歉没有更清楚地说明这一点。我已经更新了我的答案。
    猜你喜欢
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多