WCF DataContract EmitDefaultValue
2011-11-29 11:41 无名365 阅读(742) 评论(0) 编辑 收藏 举报The WCF DataContract model is ‘opt-in’; to include a member in the contract, explicitly apply the DataMemberAttribute to the field or property to include it in the serialized output. What if I want some properties to ‘opt-out’ under certain scenarios, should I be able to do this at runtime?
One possible solution is the use of the Data Member Default Values (http://msdn.microsoft.com/en-us/library/aa347792.aspx) . In .NET, all types have the concept of a default value and uninitialised, these are the initial states of the types.
The System.Runtime.Serialization.DataMemberAttribute has a property EmitDefaultValue. By default it is true which is why you may see entries in the service response like
<sig i:nil="true" >
Set DataMemberAttribute = false, and when a property is in its ‘default’ state, it wont be included in the serialization.
For example a DataContract may be described by
[DataContract]
public class DataResponse
{
public DataResponse()
{
version = "0.6";
reqId = "0";
status = "ok";
}
[DataMember(EmitDefaultValue=false) ]
public String version { get; set; }
[DataMember(EmitDefaultValue = false)]
public String reqId { get; set; }
[DataMember(EmitDefaultValue = false)]
public String status { get; set; }
[DataMember(EmitDefaultValue = false)]
public String warnings { get; set; }
[DataMember(EmitDefaultValue = false)]
public String errors{get;set;}
[DataMember(EmitDefaultValue = false)]
public String sig { get; set; }
[DataMember(EmitDefaultValue = false)]
public String table { get; set; }
}
With some properties initialised on creation, others to be completed at runtime.
If I only want to serialize the errors property when the status is equal to “errors” then EmitDefaultValue = false excludes the errors property until it is explicity set.
if (this.item.status == "errors")
{
this.item.errors = "...some error information structure...";
}
Whereupon the errors property will be included in the serialization.
Likewise by setting the property back to the default value
this.item.errors = null;
excludes it again.
This is a fairly simplistic approach to controlling the serialized structure, however it is the least intrusive without getting into Reflection and the bowels of the serialization process.