Reputation: 63
I want to inherit from a class which is located in a WCF Service. The Inheritance works fine (I see the properties of the base class in my child class), my problem occurs when I try to call a method from the service and pass the childtype as a parameter and not the basetype.
Base class in WCF Service (Pet
):
[ServiceContract]
public interface IService
{
[OperationContract]
void BringPet(Pet pet);
[OperationContract]
void TakePet(Pet pet);
[OperationContract]
List<Pet> GetAllPets();
}
[DataContract]
public class Pet
{
private string _name;
private string _color;
[DataMember]
public string Name
{
get { return _name; }
set { _name = value; }
}
[DataMember]
public string Color
{
get { return _color; }
set { _color = value; }
}
}
Class on the client (Dog
inherits from Pet
):
[DataContract()]
class Dog : PetService.Pet
{
[DataMember()]
public bool HasPedigree { get; set; }
[DataMember()]
public string Race { get; set; }
}
When I try calling something like this:
Dog dog = new Dog()
{
Color = "Black",
Name = "Pluto",
HasPedigree = true,
Race = "Travolta"
};
_client.BringPet(dog);
I get a CommunicationException
which says that the type Dog
is not expected by the method BringPet(Pet pet)
.
I would solve this problem by setting the KnownType
attributes on the service side, but because my service must not know the type Dog
I can't set the KnownType
or ServiceKnownType
attributes.
Can someone help me out?
Upvotes: 1
Views: 7636
Reputation: 2714
I think this is very similar to this question: Service - client interface, architecture advice
As you will see, there is no really easy way to do this without making your service operation more generic.
Upvotes: 2
Reputation: 755321
If you want to have inherited classes that get returned instead of the ones defined in your service contract, you need to make this fact known to WCF by means of the ServiceKnownType
attribute:
[ServiceContract]
[ServiceKnownType(typeof(Dog))]
public interface IService
{
[OperationContract]
void BringPet(Pet pet);
[OperationContract]
void TakePet(Pet pet);
[OperationContract]
List<Pet> GetAllPets();
}
This basically tells the WCF service to also allow classes of type Dog
to be used in your service.
Or you can decorate your data contract with the KnownType
attribute:
[DataContract]
[KnownType(typeof(Dog))]
public class Pet
{
.....
}
to associate your data contract type with additional types that could be used in its place.
One way or the other: you have to make your extra type known to the WCF runtime - WCF cannot figure out that fact by just checking .NET type inheritance.
Upvotes: 4