MSDN > Home page del forum > Windows Communication Foundation > WCF & KnownType : Weird Behaviour
Formula una domandaFormula una domanda
 

Con rispostaWCF & KnownType : Weird Behaviour

  • giovedì 2 luglio 2009 4.32ArefK Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    Dear All,
    I am new to WCF and I checked out the forum to find a solution but found nothing.
    BTW, I have a base class called BaseData which is defined as bellow:

        [DataContract(Namespace = "http://localhost/KnownType")]
        [KnownType(typeof(SubData))]
        public class BaseData
        {
            [DataMember]
            public virtual int ID
            {
                get;
                set;
            }
        }

    There is also a derived class called SubData:

        [DataContract(Namespace = "http://localhost/KnownType")]
        public class SubData :BaseData
        {
            [DataMember]
            public override int ID {get;set;}
        }

    As you see SubData overrides ID property. Therefore, at client side, an instance of either BaseData or SubData must have a ID property. Bur surprisingly when I create a proxy using Visual Studio, I see that an instance of BaseData has an ID , but an instance of SubData doesn't. Why it is like that??
    For your info I will bring the definition of the ServiceContract here:

    [ServiceContract]
        public interface IKnownType
        {
            [OperationContract]
            SubData GetData();
        }

        [ServiceBehavior(Namespace = "http://localhost/KnownType")]
        public class KnownType : IKnownType
        {
            public SubData GetData()
            {
                return new SubData() { ID = 10 };
            }
        }

Risposte

  • giovedì 2 luglio 2009 14.18Dhananjay25 Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con rispostaContiene codice
    Hi AreFk, 

    See  There is no probelm in your code. It is working fine for me .  You just remove your service refernece and add it again at client.  For your better undersatding , I have pasted 4 different combinations for  your code and 3rd and 4th combination is working fine. 

    So , there is no probelem in your code 

    1. Just rebuild the service 
    2. Host it again 
    3. update serveice reference at cleint and you are done my dear friend 

    I tried out three combinations to answer you . 
    First is  I replaced [DataContract]  of base class with Serilizable attribute. And I left service implentation as same of your implentation . 

        [Serializable]
        public class BaseData
        {
            [DataMember]
            public int ID { get; set; }
        }
        [DataContract]
        public class SubData:BaseData 
        {
            [DataMember]
    
            public int ID { get; set; }
        }
    }
    
    
     Surprisngly at the client side ,  I  am getting two ID , ID1 ( I know , why I am getting two ID because , I am not overriding the ID field). But I am getting ID property exposed for the subclass .

                Service1Client proxy = new Service1Client();
                SubData obj = new SubData();
                obj.ID = 9;
                obj.ID1 = 10; 
                Console.WriteLine(obj.ID);
                Console.WriteLine(obj.ID1);
                Console.ReadKey(true);
    
    Second , when I changed the class like below 
    [Serializable]
        public class BaseData
        {
            [DataMember]
            public  virtual int ID { get; set; }
        }
        [DataContract]
        public class SubData:BaseData 
        {
            [DataMember]
    
            public  override  int ID { get; set; }
        }
    


    I am not getting ID for either of the class.  where aas I am getting Idk_backingField. I am not sure whether, it is substitution of ID property  ?

                Service1Client proxy = new Service1Client();
                SubData obj = new SubData();
                BaseData baseobj = new BaseData();
                baseobj.IDk__BackingField = 10;
                obj.IDk__BackingField = 10;
                Console.WriteLine(obj.IDk__BackingField);
               Console.WriteLine(baseobj.IDk__BackingField);
                Console.ReadKey(true);
                         
    
    3rd try which is youe solution 

    I changed classes as

     [DataContract]
        public class BaseData
        {
            [DataMember]
            public  virtual int ID { get; set; }
        }
        [DataContract]
        public class SubData:BaseData 
        {
            [DataMember]
    
            public  override  int ID { get; set; }
        }
    
     and at the client side , I am getting ID property exposed for both of the classes . see the client code below. 

     Service1Client proxy = new Service1Client();
                SubData obj = new SubData();
                BaseData baseobj = new BaseData();
                obj.ID = 9;
                baseobj.ID = 10;
           
                Console.WriteLine(obj.ID);
               Console.WriteLine(baseobj.ID );
                Console.ReadKey(true);
    

    So Id for both of the classes are exposed. 

    Now coming to  your class definition 

     [DataContract(Namespace="http://localhost/KnownType")]
        [KnownType(typeof(SubData))]
        public class BaseData
        {
            [DataMember]
            public  virtual int ID { get; set; }
        }
        [DataContract(Namespace = "http://localhost/KnownType")]
        public class SubData:BaseData 
        {
            [DataMember]
    
            public  override  int ID { get; set; }
        }
    
     
    At client side both Id is exposed .

                Service1Client proxy = new Service1Client();
                SubData obj = new SubData();
                BaseData baseobj = new BaseData();
                obj.ID = 9;
                baseobj.ID = 10;
                
           
                Console.WriteLine(obj.ID);
               Console.WriteLine(baseobj.ID );
                Console.ReadKey(true);
                         
    



    Thanks Dhananjay Kumar
    My Articles on http://www.c-sharpcorner.com/Authors/AuthorDetails.aspx?AuthorID=dhananjaycoder
    Contact me at dhananjay.25july@gmail.com
    • Proposto come rispostaRahul P Nath domenica 5 luglio 2009 11.13
    • Contrassegnato come rispostaArefK domenica 5 luglio 2009 11.19
    •  

Tutte le risposte

  • giovedì 2 luglio 2009 7.22Manesh_G Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     

    While creating proxy it doesnot create implementation for inherited class properties .

    Other way is u can add your service reference in your client application and can accees
    your ID property from both classes instances


    Manesh
  • giovedì 2 luglio 2009 12.58ArefK Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    Hi Manesh
    Thanks for the reply. May you please let me know what is the difference between creating a proxy and adding a WCF service reference?

    Thanks
  • giovedì 2 luglio 2009 13.30Richard BlewettMVP, ModeratoreMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    Adding a service reference generates the code for the proxy on the client side so they are basically the same thing (although creating a proxy could also mean instantiating an instance of the proxy class)

    The contract defines what data is to be passed, it doesn;t define OO semantics for the classes contract. As far as the client is concerned it has a faithful representation of the data that the service exposes. A base class with an ID and a class that derives from it
    Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
    Twitter: richardblewett
  • giovedì 2 luglio 2009 14.18Dhananjay25 Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     Con rispostaContiene codice
    Hi AreFk, 

    See  There is no probelm in your code. It is working fine for me .  You just remove your service refernece and add it again at client.  For your better undersatding , I have pasted 4 different combinations for  your code and 3rd and 4th combination is working fine. 

    So , there is no probelem in your code 

    1. Just rebuild the service 
    2. Host it again 
    3. update serveice reference at cleint and you are done my dear friend 

    I tried out three combinations to answer you . 
    First is  I replaced [DataContract]  of base class with Serilizable attribute. And I left service implentation as same of your implentation . 

        [Serializable]
        public class BaseData
        {
            [DataMember]
            public int ID { get; set; }
        }
        [DataContract]
        public class SubData:BaseData 
        {
            [DataMember]
    
            public int ID { get; set; }
        }
    }
    
    
     Surprisngly at the client side ,  I  am getting two ID , ID1 ( I know , why I am getting two ID because , I am not overriding the ID field). But I am getting ID property exposed for the subclass .

                Service1Client proxy = new Service1Client();
                SubData obj = new SubData();
                obj.ID = 9;
                obj.ID1 = 10; 
                Console.WriteLine(obj.ID);
                Console.WriteLine(obj.ID1);
                Console.ReadKey(true);
    
    Second , when I changed the class like below 
    [Serializable]
        public class BaseData
        {
            [DataMember]
            public  virtual int ID { get; set; }
        }
        [DataContract]
        public class SubData:BaseData 
        {
            [DataMember]
    
            public  override  int ID { get; set; }
        }
    


    I am not getting ID for either of the class.  where aas I am getting Idk_backingField. I am not sure whether, it is substitution of ID property  ?

                Service1Client proxy = new Service1Client();
                SubData obj = new SubData();
                BaseData baseobj = new BaseData();
                baseobj.IDk__BackingField = 10;
                obj.IDk__BackingField = 10;
                Console.WriteLine(obj.IDk__BackingField);
               Console.WriteLine(baseobj.IDk__BackingField);
                Console.ReadKey(true);
                         
    
    3rd try which is youe solution 

    I changed classes as

     [DataContract]
        public class BaseData
        {
            [DataMember]
            public  virtual int ID { get; set; }
        }
        [DataContract]
        public class SubData:BaseData 
        {
            [DataMember]
    
            public  override  int ID { get; set; }
        }
    
     and at the client side , I am getting ID property exposed for both of the classes . see the client code below. 

     Service1Client proxy = new Service1Client();
                SubData obj = new SubData();
                BaseData baseobj = new BaseData();
                obj.ID = 9;
                baseobj.ID = 10;
           
                Console.WriteLine(obj.ID);
               Console.WriteLine(baseobj.ID );
                Console.ReadKey(true);
    

    So Id for both of the classes are exposed. 

    Now coming to  your class definition 

     [DataContract(Namespace="http://localhost/KnownType")]
        [KnownType(typeof(SubData))]
        public class BaseData
        {
            [DataMember]
            public  virtual int ID { get; set; }
        }
        [DataContract(Namespace = "http://localhost/KnownType")]
        public class SubData:BaseData 
        {
            [DataMember]
    
            public  override  int ID { get; set; }
        }
    
     
    At client side both Id is exposed .

                Service1Client proxy = new Service1Client();
                SubData obj = new SubData();
                BaseData baseobj = new BaseData();
                obj.ID = 9;
                baseobj.ID = 10;
                
           
                Console.WriteLine(obj.ID);
               Console.WriteLine(baseobj.ID );
                Console.ReadKey(true);
                         
    



    Thanks Dhananjay Kumar
    My Articles on http://www.c-sharpcorner.com/Authors/AuthorDetails.aspx?AuthorID=dhananjaycoder
    Contact me at dhananjay.25july@gmail.com
    • Proposto come rispostaRahul P Nath domenica 5 luglio 2009 11.13
    • Contrassegnato come rispostaArefK domenica 5 luglio 2009 11.19
    •  
  • sabato 4 luglio 2009 4.04ArefK Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    Hi Dhananjay25 ,
    Thank you very much for the exhaustive answer. I wrote that code within Visual Studio 2010 Beta 1 , is it possible to be a bug of VS?
    I will check that code out in  VS 2008 and will be back to you :)

    Thanks
    Aref
  • sabato 4 luglio 2009 4.31ArefK Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    Yes, it seems to be a bug in VS2010. I checked that code with VS2008 and it works fine.

    Thank you all
  • giovedì 9 luglio 2009 12.58Dhananjay25 Medaglie utenteMedaglie utenteMedaglie utenteMedaglie utenteMedaglie utente
     
    Have u cheked with VS2010. R u getting the same behavior
    Thanks Dhananjay Kumar
    My Articles on http://www.c-sharpcorner.com/Authors/AuthorDetails.aspx?AuthorID=dhananjaycoder
    Contact me at dhananjay.25july@gmail.com