Microsoft Developer Network >
Domovská stránka fór
>
Windows Communication Foundation
>
WCF & KnownType : Weird Behaviour
WCF & KnownType : Weird Behaviour
- 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 };
}
}
Odpovědi
- 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 code1. Just rebuild the service2. Host it again3. 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 .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 .[Serializable] public class BaseData { [DataMember] public int ID { get; set; } } [DataContract] public class SubData:BaseData { [DataMember] public int ID { get; set; } } }Second , when I changed the class like belowService1Client proxy = new Service1Client(); SubData obj = new SubData(); obj.ID = 9; obj.ID1 = 10; Console.WriteLine(obj.ID); Console.WriteLine(obj.ID1); Console.ReadKey(true);[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 ?3rd try which is youe solutionService1Client 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);I changed classes asand at the client side , I am getting ID property exposed for both of the classes . see the client code below.[DataContract] public class BaseData { [DataMember] public virtual int ID { get; set; } } [DataContract] public class SubData:BaseData { [DataMember] public override int ID { get; set; } }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- Navržen jako odpověďRahul P Nath 5. července 2009 11:13
- Označen jako odpověďArefK 5. července 2009 11:19
Všechny reakce
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- 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 - 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 - 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 code1. Just rebuild the service2. Host it again3. 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 .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 .[Serializable] public class BaseData { [DataMember] public int ID { get; set; } } [DataContract] public class SubData:BaseData { [DataMember] public int ID { get; set; } } }Second , when I changed the class like belowService1Client proxy = new Service1Client(); SubData obj = new SubData(); obj.ID = 9; obj.ID1 = 10; Console.WriteLine(obj.ID); Console.WriteLine(obj.ID1); Console.ReadKey(true);[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 ?3rd try which is youe solutionService1Client 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);I changed classes asand at the client side , I am getting ID property exposed for both of the classes . see the client code below.[DataContract] public class BaseData { [DataMember] public virtual int ID { get; set; } } [DataContract] public class SubData:BaseData { [DataMember] public override int ID { get; set; } }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- Navržen jako odpověďRahul P Nath 5. července 2009 11:13
- Označen jako odpověďArefK 5. července 2009 11:19
- 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 - Yes, it seems to be a bug in VS2010. I checked that code with VS2008 and it works fine.
Thank you all - 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

