skav
skav

Reputation: 1460

WCF - Custom name for a DataMember of a generic class

I have an existing WCF REST / JSON service that returns lists of different types of Data. I'd like to add to each response a single attribute which represents a revision number.

Say I have a 'Car' class

[DataContract]
public class Car {
    [DataMember]
    public String make;
    [DataMember]
    public String year;
}

Currently /cars/ returns an array of Cars, like the following

{ [ {year: "1990", make: "bmw"}, {year: "2010", make: "ferrari"} ] }

Now, I'd like for the response to be

{ revision:"1234", cars:[ {year: "1990", make: "bmw"}, {year: "2010", make: "ferrari"} ]}

This is trivial if I only have a single class of Cars, but my service has hundreds of simple entities and I'd like for each to return the revision attribute and the list of entities. I thought I could do something like the following where I create a generic class to wrap the existing item.

[DataContract]
public class VersionedItem<T> {
    String revision;
    T item;

    [DataMember]
    public String revision {
        get{}
        set{}
    }

    [DataMember]
    public T item {
        get{}
        set{}
    }
} 

This almost works great except where I need the following to be returned:

{ revision:"1234", cars:[ {year: "1990", make: "bmw"}, {year: "2010", make: "ferrari"} ] }

This is actually returned

{ revision:"1234", item:[ {year: "1990", make: "bmw"}, {year: "2010", make: "ferrari"} ] }

Question 1: is there any way to specialize an instance of the generic class to specify the correct name for the item attribute (cars in this case)? IE, (total hogwash, but to help get the point across)

public class VersionedCar : VersionedItem<Car>
{
    [DataMember(Name="cars")]
    public Car item{
        get{}
        set{}
    }
}

Question 2: if not, whats the best way to achieve wrapping all the responses and including a new attribute in all the responses?

Upvotes: 3

Views: 705

Answers (1)

krisragh MSFT
krisragh MSFT

Reputation: 1918

You can plug in an "operation formatter". For an example, using Reflector, look at how WebHttpBehavior plugs in and uses DataContractJsonSerializerOperationFormatter.

To do this, you first need to plug in your own service endpoint behavior (similar to WebHttpBehavior.) When the behavior is asked for an operation formatter, you return it your own custom formatter (similar to DataContractJsonSerializerOperationFormatter._ All this custom formatter does is serialize a version wrapper around the data it normally serializes, before delegating to its usual serialization mechanism.

You would also need a similar client behavior, and the same formatter, back on the client end, so that such messages can be processed on WCF clients.

Hope this helps!

Upvotes: 2

Related Questions