Using the new client hooks in WCF Data Services Client
What are the Request and Response Pipeline configurations in WCF Data Services Client?In WCF Data Services 5.4 we added a new pattern to allow developers to hook into the client request and response pipelines. In the server, we have long had the concept of a processing pipeline. Developers can use the processing pipeline event to tweak how the server processes requests and responses. This concept has now been added to the client (though not as an event). The feature is exposed through the
Configurations property on the
Configurations there are two properties, called
ResponsePipeline contains configuration callbacks that influence reading to OData and materializing the results to CLR objects. The
RequestPipeline contains configuration callbacks that influence the writing of CLR objects to the wire. Developers can then build on top of the new public API and compose higher level functionality.
The explanation might be a bit abstract so let’s move look at a real world example. The code below will document how to remove a property that is unnecessary on the client or that causes materialization issues. Previously this was difficult to do, and impossible if the payload was returning the newer JSON format, but this scenario is now trivially possible with the new hooks. Below is a code snippet to remove a specific property:
This code is using the
OnEntryRead response configuration method to remove the property. Behind the scenes what is happening is the
reader.Read(). As it reads though the items, depending on the
ODataItem type a call will be made to the all configuration callbacks of that type that are registered. A couple notes about this code:
IEnumerable<ODataProperty>and not an
ICollection<ODataProperty>, we need to replace the entire
IEnumerableinstead of just calling
ResolveTypeis used here to use the
TypeNameand get the
EntityType, typically for a code generated
DataServiceContextthis method is automatically hooked up but if you are using a
DataServiceContextdirectly then delegate code will need to be written.
What if this scenario has to occur for other properties on the same type or properties on a different type? Let’s make some changes to make this code a bit more reusable.
Extension method for removing a property from an
Extension method for removing a property from the
ODataEntry on the selected type:
And now finally the code that the developer would write to invoke the method above and set the configuration up:
The original code is now broken down and is more reusable. Developers can use the
RemoveProperties extension above to remove any property from a type that is in the
ODataEntry payload. These extension methods can also be chained together.
The example above shows how to use
OnEntryEnded, but there are a number of other callbacks that can be used. Here is a complete list of configuration callbacks on the response pipeline:
All of the configuration callbacks above with the exception of
OnMessageReaderSettingsCreate are called when the
ODataReader is reading through the feed or entry. The
OnMessageReaderSettingsCreate callback is called just prior to when the
ODataMessageWriter is created and before any of the other callbacks are called. The
OnEntityMaterialized is called after a new entity has been converted from the given
ODataEntry. The callback allows developers to apply any fix-ups to an entity after it was converted.
Now let’s move on to a sample where we use a configuration on the
RequestPipeline to skip writing a property to the wire. Below is an example of an extension method that can remove the specified properties before it is written out:
As you can see we are following the same pattern as the extension method we wrote to
RemoveProperties for the
ResponsePipeline. In comparison to this extension method this function doesn’t require the type resolving func, so it’s a bit simpler. The type information is specified on the
OnEntryEnding args in the
Entity property. Again this example only touches on
ODataEntryEnding. Below is the complete list of configuration callbacks that can be used:
With the exception of
OnMessageWriterSettingsCreated, the other configuration callbacks are called when the
ODataWriter is writing information to the wire.
In conclusion, the request and response pipelines offer ways to configure the how payloads are read and written to the wire. Let us know any other questions you might have to leverage this feature.
Chris Robinson – OData Team