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