I have written a ContractInvariantMethod
for a data contract class, and everything works great on the client side, however when an object of this type is sent to my service, and the Data Contract Deserializer tries to deserialize it, code contract checking gets in the way and throws ContractException
, saying invariant failed.
The reason is that in the (default) constructor of the class, i set the properties to satisfy the invariant, but apparently the constructor doesn't get called when the object is being deserialized.
is there a solution to this?
here is my data contract class:
[DataContract]
public class DataContractClass
{
public DataContractClass()
{
this.Field1= this.Field2= -1;
}
[DataMember]
public int Field1 {get; set;}
[DataMember]
public int Field2 {get; set;}
[ContractInvariantMethod]
private void Invariants()
{
Contract.Invariant(this.Field1== -1 || this.Field2== -1);
}
}
Most important, the DataContractSerializer is used to serialize and deserialize data sent in Windows Communication Foundation (WCF) messages. Apply the DataContractAttribute attribute to classes, and the DataMemberAttribute attribute to class members to specify properties and fields that are serialized.
DataContractSerializer as the Default By default WCF uses the DataContractSerializer class to serialize data types.
Json namespace. If your scenario requires the DataContractJsonSerializer class, you can use it to serialize instances of a type into a JSON document and to deserialize a JSON document into an instance of a type.
The process forms a sequence of bytes into a logical object; this is called an encoding process. At runtime when WCF receives the logical message, it transforms them back into corresponding . Net objects. This process is called serialization.
During runtime checking, invariants are checked at the end of each public method.
So when the Serializer set Property1 and Property2 not to -1 you get a contract exception because the deserializer dont use the constructor.
So use this:
public DataContractClass()
{
SetDefaults();
}
[OnDeserializing]
private void OnDeserializing(StreamingContext context)
{
SetDefaults();
}
private void SetDefaults()
{
Property1 = -1;
Property2 = -1;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With