Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an instance of anonymous type over WCF

Tags:

I have a WCF service method that expects an object and then retrieves its properties using reflection.

On the client side I create an anonymous type object

var obj = new {FirstName="John", LastName="Doe"} 

and pass it to the method. I'm getting an exception:

Type '<>f__AnonymousType0`2[System.String,System.String]' cannot be serialized.  Consider marking it with the DataContractAttribute attribute, and marking all  of its members you want serialized with the DataMemberAttribute attribute.   See the Microsoft .NET Framework documentation for other supported types. 

I can't mark the type or its members with serialization attributes because there is really no type nor properties declared explicitly. Is there a way to overcome that problem?

like image 231
Andrey Avatar asked Feb 21 '10 19:02

Andrey


2 Answers

The answers suggesting that you can't use an anonymous type over WCF are wrong.

If you are using the default DataContractSerializer to serialize your types on the channel, then yes, the answers are correct. This is because the DataContractSerializer supports the following scenarios:

  1. Types serialized using the Serializable attribute
  2. Types serialized using XML Serialization
  3. Types serialized using the DataContract attribute
  4. Plain-Old-C#-Object (POCO) Serialization

Respectively, they fail with anonymous types because of the following:

  1. You can't apply attributes to anonymous types.
  2. XML Serialization requires a default parameterless constructor, which anonymous types do not have.
  3. Same as 1.
  4. Same as 2.

However, you are not forced to use the DataContractSerializer to serialize your messages in WCF. You can create a custom message formatter which you can use to perform the serialization yourself.

You have a problem if the types you are sending out as the results of requests are anonymous types. When you get the results back, it's going to have a definite name within a namespace (not in a .NET sense, but in a SOA sense) and you are going to have to handle the mapping of that concrete type back to the anonymous type. However, because you don't have access to the actual anonymous type or ways of constructing it in code (at least in a dynamic way), you have no choice but to pass it along as an object if it's passed back to you, which makes it kind of worthless, since everyone will have to use bad practices such as dynamic (not a bad practice in itself, but to get around these limitations in this case, yes), or cast-by-example.

So in the end I will say that while it certainly is possible to serialize anonymous types and send them over the wire, the work invovled is usually not worth it.

like image 108
casperOne Avatar answered Sep 20 '22 14:09

casperOne


Don't do this.

It's an attempt to be clever. Don't. Just declare the datatype you need, and use it. If you need a more loosely-defined datatype, just use a key-value mapping of some sort.

It will take you 5 minutes to write something that can handle this for good. Using any technique like this will cost you hours of debugging at some future point down the road.

like image 31
kyoryu Avatar answered Sep 20 '22 14:09

kyoryu