Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF - serializing inherited types

I have these classes:

[DataContract]
public class ErrorBase {}

[DataContract]
public class FileMissingError: ErrorBase {}

[DataContract]
public class ResponseFileInquiry
{
  [DataMember]
  public List<ErrorBase> errors {get;set;};
}

An instance of the class ResponseFileInquiry is what my service method returns to the client. Now, if I fill ResponseFileInquiry.errors with instances of ErrorBase, everything works fine, but if I add an instance of inherited type FileMissingError, I get a service side exception during serialization:

Type 'MyNamespace.FileMissingError' with data contract name 'FileMissingError' 
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.'

So serializer is getting confused because it's expecting the List to contain the declared type objects (ErrorBase) but it's getting inherited type (FileMissingError) objects.

I have the whole bunch of error types and the List will contain combinations of them, so what can I do to make it work?

like image 419
Andrey Avatar asked Feb 24 '10 20:02

Andrey


People also ask

What is used if you expect the service to accept and return inherited types?

If you expect the service to accept and return an inherited type then we use the knowntype attribute.

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.

What is the KnownType attribute in WCF?

The [KnownType] attribute informs the WCF service that "it is ok" to receive this Admin type because it is a subclass of the awaited UserAccount type. It is especially important when the Admin subclass has more properties, like a public string AdminEmail { get;set; } . This property will be sent by the client too.

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.


2 Answers

You should add KnownType attribute to your base class

[DataContract]
[KnownType(typeof(FileMissingError))]
public class ErrorBase {}

Read more about KnownType attribute in this blog

like image 69
Arsen Mkrtchyan Avatar answered Oct 24 '22 09:10

Arsen Mkrtchyan


Try this:

[DataContract]
[KnownType(typeof(FileMissingError))]
public class ErrorBase {}

As the error message states, any information that cannot be know statically (like the polymorphic relationship you have expressed here) must be supplied via attributes. In this case you need to specify that your FileMissingError data contract is a known type of its base class, ErrorBase.

like image 30
Andrew Hare Avatar answered Oct 24 '22 09:10

Andrew Hare