Martin
Martin

Reputation: 40573

How to exclude properties from serialization without modifying the class?

I have a WCF REST Web Service which returns POCO entities generated by Entity Framework 4. Based on the ContentType of the HTTP request, the service can return XML or JSON. This is exactly what I need. However, some of the entities have too many properties and I don’t want to return all this data. Here is how my method looks right now:

public IEnumerable<Task> GetTasks()
{
    Tasks myTasks = ...
    return myTasks;
}

I don’t want to see all the properties of the Task class, so I though of returning an XElement object instead. This gives me full control on the XML and it works like a charm. However, I am losing the JSON functionality part of WCF.

public XElement GetTasks()
{
    Tasks myTasks = ...
    return new XElement("Tasks", myTasks.Select(a => ToXml(a));
}

How do I exclude properties (without modifying the class, I might need those properties in another method) without losing the XML / JSON response handled by WCF?

Upvotes: 0

Views: 646

Answers (2)

Ladislav Mrnka
Ladislav Mrnka

Reputation: 364249

I agree with DTO but I'm not sure if AutoMapper is the tool for this scenario. Basically you want to return limited set of data. In the world of WCF it means you need another class = DTO. AutoMapper is a great tool to map from one class to other class but it means that you must load whole object from database. But why to load the whole object with all its properties if you don't need them in the requested operation? Use Linq-to-entities projection instead. It requires to do mapping manually but it is more effective approach.

public IEnumerable<TaskDto> GetTasks()
{
    return context.Tasks.Select(t => new TaskDto
        {
            Name = t.Name,
            DueDate = t.DueDate
        }).AsEnumerable(); 
}

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

You could use a DTO object and then map between the model and this object. AutoMapper is a great framework for this:

public IEnumerable<TaskDto> GetTasks()
{
    IEnumerable<Task> myTasks = ...
    IEnumerable<TaskDto> tasks = Mapper.Map<IEnumerable<Task>, IEnumerable<TaskDto>>(myTasks);
    return tasks;
}

Feel free to include whatever properties you need in this object.

Upvotes: 0

Related Questions