Can I tell the WCF WebAPI serializer to ignore nested class objects? - serialization

I am using WCF WebAPI to write REST services using WCF.
I am returning my POCO classes as json/xml objects from my service.
Most of my POCO classes contain ICollections as they are part of EF4.1 Code First,
hence I get error :
Cannot serialize member of type ...
System.Collections.Generic.ICollection ... because it is of type -
because it is an interface
To avoid that XMLIgnore and ScriptIgnore is suggested. And there are some problems in custom serialization of JSON in WCF.
Just thought someone might have come across a similar problem and have a better solution or way to configure serialization classes, otherwise I will have to decorate each such attribute with XMLIgnore, etc.

More often than not you probably would use DTOs or (view models in ASP.NET MVC) to decouple from your domain model. And you can use AutoMapper to minimize your code converting between domain models and DTOs.

You have to add [XmlIgnore] and [IgnoreDataMember]. Then the property will be ignored for xml and json response.

Thats right Sandro, [IgnoreDataMember] and [XmlIgnore] is needed.
A little bit more explaination:
[IgnoreDataMember] is needed to exclude the field in json serialization,
[XmlIgnore] is needed to exclude the field in xml serialization.

I found that in WCF WebAPI [ScriptIgnore] or [JsonIgnore] are not working and have no effect, so I'm going back to ASP.NET MVC for json-related REST APIs.
Update[24-Jul-2012] This answer is old, and Microsfot WebAPI has come a long way since, please check before relying on this answer.

Related

WCF: how to create a large number of classes in the contract?

Well, I am creating a WCF service, that have a large number of classes to communicate with the client, and this classes have also many properties.
Mainly, this classes are the POCO classes that is created with the code generator from the edmx, and I have the .tt file.
To can use this classes and properties, I have to use the DataContract and DataMember, so in each classes I have to set the DataContract and in each property of the each class the DataMemeber. So this a big work, so if I need to do some modify to the data base, I must generate again the tt file and then repeat the work.
Is there any way to do this automatically? I am using .NET 4.0 and EF 4.1.
The whole point of the .tt file being added to your project is so that you can modify the template to suit your needs. All you need to do is change the template so that it adds [DataContract] to the entity class definition and [DataMember] to the entity property definitions.
From there, any time the DB is changed you simple use the "Update model from database" feature and your entities will automatically have their code regenerated using the existing template.
All that said, I'm going to recommend you do not expose your DB entities, POCO or not, directly from your service layer. You should really be designing with domain separation and using messaging and CQRS type patterns at the service level. Then you just have some simple mapping methods that translate the data between those messages/commands to your entities.
There is Entity Framework Provider with WCF data services, might be it can help you.

Do we need DataContract attribute on POCO classes in Ado.net entity Framework 2010

I read somewhere in stackoverflow itself that when we use POCO classes for WCF contracts using Poco generator , we need not use DataContract and DataMember attributes.WCF do it auto for you? . I don't know how it manages this.
I created a sample application without using these attributes and I was able to generate those entities on client side and use them. I disabled proxy generation and Lazy loading.
Am i missing anything here.? Is there really no need of putting these attributes.
You did it right way. Since WCF 3.5 SP1 it is not needed to add DataContract and DataMember attributes. If attributes are not used all properties with public getter and setter are serialized.

About serialize the object having generic type in WCF

I implemented a generic way to get the object by id from Entities defined in Entity Framework.
But the problem is the object I got has a very weird type like this
{System.Data.Entity.DynamicProxies.MyEntity_C71732021C3A9D6A58BDB6087D29E98CFDE09DA9D53AF0892AFB7918AEF7E61F}
And WCF will fail when serialize this object as the type of MyEntity.
How to make the generic type to be the specific type I want?
It sounds like you're using Entity Framework 4.0 POCO objects. If that's the case, MSDN has a great walk-through on how to get things working:
Walkthrough: Serialize POCO Proxies with WCF
Also take a look at:
Working with POCO Entities (pay close attention to the Serializing POCO Proxies section)

How can I transfer an NHibernate PersistentGenericSet over WCF

I'm trying to send objects retrieved by NHibernate over WCF, but whenever a have a property of ICollection I get an exception.
When NHibernate gets the data from the database this property is intitialized with an instance of PersistentGenericSet.
Is there a way I can send a PersistentGenericSet over WCF?
-or-
Is there some way making NHibernate initialize these properties with another type?
The PersistentGenericSet is part of NHibernate (used to track changes in collections). It is based on the ISet interface and classes from Iesi.Collections, which was used to fill a gap in the .Net framework as there isn't a Set type. I guess that WCF has a problem serializing this type.
A quick fix is to change your NHibernate mappings to use a Bag instead of a Set. Then you can use a normal IList<T> instead of Set<T> in your classes w.
A better solution is to create a remote facade which sends DTOs to your WCF endpoints. This will allow you to keep the interface of your internal types separate from those exposed as remote services. Jimmy Bogards Automapper is a great tool which will help with the mapping process.
Edit
After re-reading the problem I had a look around the and came across this article which describes a workaround for sending NHibernate collections over WCF. David Brion has written a good follow up article.

WCF Contracts from Entity Framework?

I've been coming up with a lot of dead ends on this question. Supposedly, .NET 3.5 SP1 has Support for ADO.NET Entity Framework entities in WCF contracts. But when I look for solid info on it I'm not getting a lot of answers. I found this one snippet on an MSDN thread. Does anyone have any experience with this? What happened to the [DataContract]? Is this all there is to it? Why is there so little material on this?
This the answer from Tim Mallalieu in Microsoft.
Entity Types that are generated in the Entity Framework are, by default Data Contracts.
If I were to create a simple model in the Entity Designer like the following:
The cart Entity Type is by default a DataContract with all properties annotated as data members. We can then use this in a WCF service as follows:
[ServiceContract]
public interface IService1
{
[OperationContract]
Cart[] AllCarts();
}
public class Service1 : IService1
{
public Cart[] AllCarts()
{
using (MSPetShop4Entities context = new MSPetShop4Entities())
{
var carts = from c in context.Carts select c;
return carts.ToArray();
}
}
}
As the Entities are DataContracts you can now roll your services as you see fit and send these across the wire.
I recommend that you not return Entities directly. Unfortunately, Microsoft chose to include implementation-specific data as part of the DataContract for entities. This will not interoperate with other platforms, and is the sort of thing that might fail to interoperate even between .NET versions.
Instead, I recommend you follow the Data Transfer Object pattern and just return POCO classes that are copies of the data in the entities, with no behavior. You can return List of such classes to represent a table, etc.
The "sharing interfaces and not type" tenet presupposes that you don't own both ends of the wire and/or you're writing a public-facing web service. WCF can be used (and is used) in contexts where this is decidedly not the case. Many enterprise n-tier architectures have a WCF-fronted application tier to facilitate load-balancing among other things. In these cases it is perfectly valid to share type and, in fact, is desired.
You could go the easy way and use ADO.NET Data Services.
Some more detail in response to comments:
There are several problems with the classes generated by EF. I'm looking now at an AdventureWorks example with SalesOrderHeader and SalesOrderDetail. The SalesOrderDetail entity has both "SalesOrderHeader" and "SalesOrderHeaderReference" properties, both marked as DataMembers. This looks like a bug, since the "SalesOrderHeader" property is also marked [XmlIgnore] and [SoapIgnore].
Also, consider whether you want to serialize the link back to the parent SalesOrderHeader in the first place. Besides, what exactly should be serialized? SOAP doesn't support references in an interoperable manner.
Finally, the base classes of the entities are also data contracts. Yet they have nothing to do with the data you are returning - they are purely an implementation artifact.
In short, Microsoft screwed up on this one. They didn't think it through.
About ways to generate the DTO classes, I suggest looking into various code generation tools, like CodeSmith. You can write code to do this yourself; I did so in my previous position. The nice thing about generating the DTO is that you also get to generate the methods to translate to and from the DTO.
As to overhead, the overhead of moving some data around in memory is nothing compared to the amount of time it's going to take to send the data over a network!