none
Business entity contstuctor never called

    Question

  • We are working on a application that has the business entity classes on both the client and server in a WCF implementation.  We used the svcutil.exe with a reference (/r) to the business entities to generate the proxy class for the client.

    We have a private dictionary to hold validation errors on the class and instantiate the dictionary in the constuctor.  The IsValid method returns true if there are no errors in the error dictionary.

    The validation code in the setters checks the "value" and if it does not pass validation it adds a message to the error dictionary, if it does pass validation it removes errors from the dictionary if they are present.

    The problem that we are haveing is that the constructor is never called, so we had to add:

    if ( _errorDictionary == null )

    {

        _errorDictionary = new errorDictionary();

    }

    everytime before the errorDictionary is called.

    Is this expected behavior, or is there a way to get the constructor to fire before the object is rehydrated?

    Thanks for any help!

    Shannon

    Thursday, January 11, 2007 10:49 PM

Answers

  • The constructor of the classes aren't called on deserialization of [DataContract] or [Serializable] types - the serializer simply gets an "uninitialized" object and then populates the fields based on the data being deserialized. If you want to do any initialization before or after the fields are deserialized, you can use the [OnDeserializing] or [OnDeserialized] callback methods, like in the example below:

    [DataContract]
    public class MyClassWithSpecialInitialization
    {
        List<string> myList;
        string str1;
        [
    DataMember]
        public string Str1
        {
            get { return str1; }
            set
            {
                this.myList.Add(value);
                str1 =
    value;
            }
        }
        string str2;
        [
    DataMember]
        public string Str2
        {
            get { return str2; }
            set
            {
                this.myList.Add(value);
                str2 =
    value;
            }
        }
        public MyClassWithSpecialInitialization()
        {
            this.myList = new List<string>();
        }
        [
    OnDeserializing]
        public void OnDeserializing(StreamingContext context)
        {
            Console.WriteLine("Before deserializing the fields");
            this.myList = new List<string>();
        }
        [
    OnDeserialized]
        public void OnDeserialized(StreamingContext context)
        {
            Console.WriteLine("After deserializing the fields... myList should be populated with the values of str1 and str2");
        }
    }

     

    Friday, January 12, 2007 1:09 AM

All replies

  • The constructor of the classes aren't called on deserialization of [DataContract] or [Serializable] types - the serializer simply gets an "uninitialized" object and then populates the fields based on the data being deserialized. If you want to do any initialization before or after the fields are deserialized, you can use the [OnDeserializing] or [OnDeserialized] callback methods, like in the example below:

    [DataContract]
    public class MyClassWithSpecialInitialization
    {
        List<string> myList;
        string str1;
        [
    DataMember]
        public string Str1
        {
            get { return str1; }
            set
            {
                this.myList.Add(value);
                str1 =
    value;
            }
        }
        string str2;
        [
    DataMember]
        public string Str2
        {
            get { return str2; }
            set
            {
                this.myList.Add(value);
                str2 =
    value;
            }
        }
        public MyClassWithSpecialInitialization()
        {
            this.myList = new List<string>();
        }
        [
    OnDeserializing]
        public void OnDeserializing(StreamingContext context)
        {
            Console.WriteLine("Before deserializing the fields");
            this.myList = new List<string>();
        }
        [
    OnDeserialized]
        public void OnDeserialized(StreamingContext context)
        {
            Console.WriteLine("After deserializing the fields... myList should be populated with the values of str1 and str2");
        }
    }

     

    Friday, January 12, 2007 1:09 AM
  • Thanks Carlos,

    That fixed the problem.

    Shannon

     

     

    Friday, January 12, 2007 5:17 AM