views:

54

answers:

2

Imagine I've got a data object that makes sense in an OO model, but for serialization I want to have its fields referencing other types replaced with simply an ID, or in some cases, a simple object with a text and an ID.

Is it possible to have the serializer to handle specific fields differently, or do I have to redefine a second data object class from scratch with the simplified fields and use that?

Example:

Person
  Guid Id
  string Name
  List<Person> Siblings

What I want to be serialized:

Person
  Guid Id
  string Name
  List<Guid> Siblings

I would like to only have the one class, Person, and define the serialization behavior for my service (preferably not at a data type level, since it could be serialized as both XML or JSON).

I know about the support for references in WCF, but in this case I will be referencing other types not included elsewhere in the result set; I only want to include their ids.

+1  A: 

Once you change the structure of the information being transmitted, a data transfer object is probably the cleanest and simplest choice.

In fact, I would always recommend creating dedicated DTOs for WCF services, to separate the service and the data it transmits from the domain model I'm normally working against. There is the overhead of managing changes with the model and service separately, but it's much less work than having to force your domain objects into the right shape for your service and then trying to keep them there.

Programming Hero
I see. I didn't want to force my domain objects to conform to my WCF service though, I want them to be completely untouched by anything related to the service. What I wanted was a way to "inherit" the structure of the domain object, only handling a few specific cases (reference lists) differently, so that I don't get as much overhead.
Blixt
I don't think I understand the problem enough. Can you do anything to clarify your question?
Programming Hero
Hmmm... I guess the only way to do what I want is to have a callback that is called by the serializer for every item in a collection. The callback would return an object with only the values I want, which is serialized and put in the serialized collection. So basically, for the `Siblings` collection, the serializer would call the callback for every `Person` instance, and the callback would return a `Guid` value instead. This way I don't need an extra class, and I get the serialized structure I want. Is this possible with WCF?
Blixt
+1  A: 

You could exclude Siblings property from serialization and add a readonly SiblingGuids:

Person
  Guid Id
  string Name
  [NonSerialized]
  List<Person> Siblings
  List<Guid> SiblingGuids // Only a getter which will expose guids
Darin Dimitrov
I'll be going with this solution even if it's not ideal (normally I wouldn't want to make properties return values that require the creation of an object - in this case a `List` - when retrieved).
Blixt