Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Service object serialization

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.

like image 294
ancdev Avatar asked May 15 '12 14:05

ancdev


People also ask

How do you serialize an object in WCF?

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.

What is by serialization with respect to WCF?

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.

Which namespace is used for serialization in WCF?

By default WCF uses the DataContractSerializer class to serialize data types.

What is the type of serializer used in WCF?

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.


1 Answers

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.

like image 133
Sam Holder Avatar answered Sep 20 '22 12:09

Sam Holder