How to make code contracts work with deserialization of data contracts?
Asked Answered
T

1

7

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);
 }
}
Tract answered 7/8, 2011 at 11:7 Comment(2)
are you able to show us an example of your code? It may help.Benzene
i changed the question to include the code.Tract
S
6

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;
}
Shudder answered 7/8, 2011 at 12:21 Comment(1)
yes, that's right, but is there a way to make it work? like forcing the constructor to run when the object is being deserialized and before any properties are set?Tract

© 2022 - 2024 — McMap. All rights reserved.