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.
This code constructs an instance of the DataContractSerializer that can be used only to serialize or deserialize instances of the Person class. DataContractSerializer dcs = new DataContractSerializer(typeof(Person)); // This can now be used to serialize/deserialize Person but not PurchaseOrder.
The process forms a sequence of bytes into a logical object; this is called an encoding process. At runtime when WCF receives the logical message, it transforms them back into corresponding . Net objects. This process is called serialization.
By default WCF uses the DataContractSerializer class to serialize data types.
Windows Communication Foundation (WCF) uses the DataContractSerializer as its default serialization engine to convert data into XML and to convert XML back into data. The DataContractSerializer is designed to serialize data contract types.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With