Conditional Property Serialization - per web request

Dec 16, 2012 at 1:49 AM

In some applications, its handy to allow the consumer of a web endpoint to specify which subset of properties they want in the returned object graph, customized per request. The caller would indicate which properties they want in the querystring/request. There is a need to customize the serialization per request, not per type structure. I cant think of an ideal way to solve this - ideally its not enforcing any changes to view models (the objects to get serialized), but just enabling this feature per endpoint (eg by placing an attribute on the endpoint).  
There is a way to do this today, for example in MVC4/Web Api, but its not ideal. The ShouldSerialize predicate on a JSonPropery is almost what is needed without having to change any view models, except the callback only provides the instance/object and no context (which properties the user wants, where you are in the object graph). If you are ok with just filtering on one type then this would work (if you use the request-global HttpContext) but that wont work for a more general solution to do hierarchical filtering and/or when a type can appear in multiple levels in the object graph.
For now, one way I see to do this would be to have a base class/interface for the view models that get serialized, and then implement ISerializable. You'd also have to write your own MediaTypeFormatter so you could stuff things into the streaming context to do the work thats needed for filtering, things such as the fields specified in the querystring, and access to the writer which has the handy Path property that can be used to easily do hierachical and/or wild card filtering of property names. 
I dont see a way without having to touch the view model objects. We would need added features in the serializer. One way would be to add the streaming context to the ShouldSerialize callback signature (probably need a new method on the JSonProperty interface unless the format of the passed in instance object can be optionally specified to also contain the streaming context). Its still our job to add the logic for filtering by property name. Another way could be to bake the logic onto the JSonSerializerInternalWriter::ShouldSerialize method and conditionally enable the feature in a serialization setting. 
Any other ideas on how to do this without touching the view models?