Reputation: 207
I have one abstract class named contact and another class called client that inherits from contact. I'm dealing with a WCF Service with a method that takes a parameter of type contact. however what I have is an instance of client that I want to pass. Im facing this Error:
Type 'xxx.Client' with data contract name 'Client:http://schemas.datacontract.org/2004/07/xxx' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
Upvotes: 8
Views: 5736
Reputation: 32936
you ned to let DataContractSerializer know that a Client
is a type of Contact
.
There are several ways to do this, but they all revolve around using the KnownType
attribute or the ServiceKnownType
attributes.
The KnownType
can be placed on the Client
class to tell DataContractSerializer that it is a KnownType of Contact
.
[DataContract]
[KnownType(typeof(Client))]
public class Contact{}
The KnownType
can also be placed on a class to indicate that when serialising this class you may also encounter this other class.
You may want to do this if you have a DataContract
class that has a property which is a Contact
which may actually contain a Client
:
[DataContract]
[KnownType(typeof(Client))]
public class Meeting
{
Contact MeetingContact{get;}
}
In this case you could get away without specifying the KnownType on the Client. You may also want to do this if you have a property which returns a collection and you want to specify the types which can be in the collection.
You may, instead of specifying the actual type of the KnownType, specify the name of a static method which will return the known types instead:
[DataContract]
[KnownType("GetKnownTypes")]
public class Meeting
{
Contact MeetingContact{get;}
private static Type[] GetKnownType()
{
return new Type[]{typeof(Client)};
}
}
You can also specify the known type through the configuration file.
ServiceKnownTypes work in a similar way, but are specified on the Service itself:
[ServiceKnownType(typeof(Client))]
[ServiceContract()]
public interface IMyServiceContract
{
[OperationContract]
Contact GetContact();
}
This set up will let the DataContactSerializer know that any of the methods may return a type of type Client
. In a similar way to the known types you can also use a static method to provide the service known types.
Upvotes: 7
Reputation: 14919
WCF does not directly works on abstract classes. You shall use KnownType attributes on the datacontract or service class. below are examples;
[DataContract]
[KnownType(typeof(Client))]
public class Contact
{
...
}
[ServiceContract]
[ServiceKnownType(typeof(Client))]
public interface IMyService
{
contact getcontact(Guid id);
}
Upvotes: 5
Reputation: 2481
Use the [KnownType] and [ServiceKnownType] attributes to ensure the relationships.
Upvotes: 2