5

我有这样的数据合同

[DataContract]
class MyDC 
{
    [DataMember]
    public string DM1;

    [DataMember]
    public string DM2;

    [DataMember]
    public string DM3;
}

有时我想防止 DM2 在从 OperationContract 返回时被反序列化像这样的东西:

[OperationContact]
public MyDC GetMyDC()
{
    MyDC mdc = new MyDC();

    if (condition)
    {
        // Code to prevent DM2 from being deserialized  
    }

    return mdc;
}

我总是可以创建一个只有 DM1 和 DM3 的新 DataContract 并从 MyDC 实例生成它,但我想看看是否可以以编程方式删除 DM2。是否可以?如何?

4

4 回答 4

6

一种方法是将 DataMemberAttribute 的 EmitDefaultValue 属性设置为 false:

[DataContract]
class MyDC 
{
    [DataMember]
    public string DM1;

    [DataMember(EmitDefaultValue = false)]
    public string DM2;

    [DataMember]
    public string DM3;
}

然后将此属性设置为 null:

[OperationContact]
public MyDC GetMyDC()
{
    MyDC mdc = new MyDC();

    if (condition)
    {
        // Code to prevent DM2 from being deserialized  
        mdc.DM2 = null;
    }

    return mdc;
}

这样,该属性不会在序列化时写入输出流。

http://msdn.microsoft.com/en-us/library/aa347792.aspx

于 2010-08-10T13:20:14.307 回答
3

你的意思是序列化而不是反序列化。

如果您准备一个用于序列化的类,将[DataContract]属性应用于该类,则只有具有该属性的类的成员[DataMember]才会被序列化:

[DataContract]
class MyDC 
{
    [DataMember]
    public string DM1;

    public string DM2;

    [DataMember]
    public string DM3;
}

在一些更复杂的情况下,使用[IgnoreDataMember]可以解决您的问题。(参见http://msdn.microsoft.com/en-us/library/ms733127.aspx

顺便说一句,无论可访问性如何,您都可以序列化字段和属性:privateprotectedinternalprotected internalpublic. 您可以序列化任何读/写属性,而不仅仅是字段。关于集合类型的序列化,请参见http://msdn.microsoft.com/en-us/library/aa347850.aspx

于 2010-07-30T09:32:06.763 回答
2
[DataContract]
class MyDC 
{
    [DataMember]
    public string DM1;

    public string DM2;

    public bool IsDM2Serializable;

    [DataMember(Name="DM2", EmitDefaultValue = false)]
    public string DM2SerializedConditionally
    {
        get
        {
            if(IsDM2Serializable)
                return null;
            return DM2;
        }
        set { DM2=value; }
    }

    [DataMember]
    public string DM3;
}

然后在需要隐藏时将 IsDM2Serializable 设置为 false:

[OperationContact]
public MyDC GetMyDC()
{
    MyDC mdc = new MyDC();

    if (condition)
    {
        // Code to prevent DM2 from being serialized  
        mdc.IsDM2Serializable = false;
    }

    return mdc;
}
于 2012-11-06T18:30:19.643 回答
0

是的,我们可以防止属性序列化。将[DataContract]注释放在类上并且[DataMember]仅用于序列化属性。如果您想在该属性值为 null 时跳过该属性,则放入[DataMember(EmitDefaultValue = false)]该属性。

例子:

[DataContract]
public class MyClass 
{
    [DataMember]
    public int Id{ get; set; } 
    [DataMember]
    public string Title { get; set; }
    [DataMember]
    public string MessageBody { get; set; }

    [DataMember(EmitDefaultValue = false)]
    public DateTime SentOn { get; set; } 
}

注意:当 SentOn不为 null时将被序列化,其他将在每个条件下都将被序列化。

于 2019-04-30T12:28:34.550 回答