Can I prevent a specific datamember from being deserialized?
Asked Answered
P

4

5

I have a datacontract like this

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

    [DataMember]
    public string DM2;

    [DataMember]
    public string DM3;
}

and sometimes I want to prevent DM2 from being deserialized when being returned from an OperationContract. Something like this:

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

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

    return mdc;
}

I could always make a new DataContract that has only DM1 and DM3 and generate that from the MyDC instance but I want to see if it is possible to programatically remove DM2. Is it possible? How?

Preglacial answered 29/7, 2010 at 0:10 Comment(0)
O
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;
}

Then set IsDM2Serializable to false when you need to hide it:

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

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

    return mdc;
}
Observance answered 6/11, 2012 at 18:30 Comment(0)
E
6

One way to do this is to set the EmitDefaultValue property of the DataMemberAttribute to false:

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

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

    [DataMember]
    public string DM3;
}

Then setting this property to null:

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

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

    return mdc;
}

This way, that property doesn't get written to the output stream on serialization.

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

Ezaria answered 10/8, 2010 at 13:20 Comment(1)
That works if I am creating a copy of the actual object I want to serialize, and don't care about changing the copy. However, I would like to do it without changing the object I am trying to serialize.Preglacial
D
3

What you mean is serialization and not deserialization.

If you prepare a class for serialization applying the [DataContract] attribute to the class, only the members of the class that has [DataMember] attribute will be serialized:

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

    public string DM2;

    [DataMember]
    public string DM3;
}

In some more complex cases the usage of [IgnoreDataMember] can solve your problem. (See http://msdn.microsoft.com/en-us/library/ms733127.aspx)

By the way, you can serialize fields and properties, regardless of accessibility: private, protected, internal, protected internal, or public. You can serialize any read/write properties and not only fields. About serialization of collection types see http://msdn.microsoft.com/en-us/library/aa347850.aspx.

Duval answered 30/7, 2010 at 9:32 Comment(0)
O
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;
}

Then set IsDM2Serializable to false when you need to hide it:

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

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

    return mdc;
}
Observance answered 6/11, 2012 at 18:30 Comment(0)
A
0

Yes, we can prevent an attribute from serialization. Put [DataContract] Annotation on class and [DataMember] for only serialized attribute. if you want to skip attribute when that attribute value is null then put [DataMember(EmitDefaultValue = false)] on that attribute.

Example:

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

Note: SentOn will be serialized when it is not null and others will be serialized in every condition.

Almanza answered 30/4, 2019 at 12:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.