Recently I observed a strange behavior when working with an ODATA service via a “System.Data.Services.Client.DataServiceContext” that was wrapped inside a class library (via a regular “Service Reference”). The specific ODATA service in question was an Entity Framework v4.1 based service and had defined two different entity sets (“Objects” and “Tasks”) along with its regular CRUD operations. The specialty of the “Objects” entity set was, that it returned an entity from the “Tasks” entity set on a PATCH/PUT operations instead of returning HTTP 204 or an “Object” entity.

So whenever you execute a “SaveChanges()” method on the DataServiceContext on such an “Object” you will get “Task” object in return (along with an HTTP 202). When tracing the code in Visual Studio you see that the operation is actually completely and successfully executed. And another look at Fiddler will then show you the correct HTTP 202 response. However, within the PowerShell session you will get a generic exception stating the “save operation failed”. Investigating the InnerException of the Exception in the ErrorRecord will will reveal that there is might be an invalid property received from the server. The reason behind this is, the DataServiceContext tries to convert the returned data into an entity of type “Object” instead of “Task”. And the properties of these object types do not match and hence the context cannot perform the conversion.

The behaviour is actually surprising as the HTTP response body contains a well formatted ODATA type description of the returned entity (“Task”). So the class library should actually be able to tell the correct return type and not try to convert the body to the entity type of the saved entity.

Luckily there is a workaround this by setting a property on the DataServiceContext called IgnoreMissingProperties. Once you set this property to “true” (it is “false” by default) you will not get an exception any more and be able to retrieve the (raw) data from the response. In case you want to convert the raw (json) data from the response to a native .NET object you can then manually deserialise as described in More Fun with ODATA Actions in PowerShell:

PS > Add-Type -AssemblyName System.Web.Extensions;
PS > $jss = New-Object System.Web.Script.Serialization.JavaScriptSerializer;
PS > $jss.Deserialize

OverloadDefinitions
-------------------
T Deserialize[T](string input)
System.Object Deserialize(string input, type targetType)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.