Just another tech site

oData v3 and DataServices 5.0

oData interception

One of the coolest thing with DataServices is that you can really quickly setup your oData Service.
Now if you wish to intercept the call and to perform specific operation it is of course possible.
In this small example we will see how to create the service and make the modification in order to have an end to end call.
The example uses oData version 3 and .NET DataService 5.0 (available under NuGet)

The Data Service

Here is the classic service definition

// Expose IQueryable properties as read-only Atom collections
public class CustomerDataService : DataService

#region Data Service Initialize Service

public static void InitializeService(DataServiceConfiguration config)
config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;

In this case “CustomerService” is an Iqueryable. For example a dbcontext.

WCF interception

In the service definition we need to add the interception of the call and the analysis of the URI.
The idea is to extract the custom elements in the querytring.
The key event is the “OnStartProcessingRequest” that will be called upon reception.

// Expose IQueryable properties as read-only Atom collections
public class CustomerDataService : DataService

#region These elements will allow us to parse the query string for non oData elements

DataServiceOperationContext OpsContext;
Dictionary<string, string> QueryParameters;

/// GetQueryParameterBag
Dictionary<string, string> GetQueryParameterBag(DataServiceOperationContext serviceOperationContext)
Dictionary<string, string> ParameterBag = null;
string query = serviceOperationContext.AbsoluteRequestUri.Query;

if (!string.IsNullOrEmpty(query))
ParameterBag = new Dictionary<string, string>();
query = query.Remove(0, 1);
string[] param = query.Split('&');

string paramName;
string paramValue;

foreach (var item in param)
//Skip OData supported parameters
if (!item.StartsWith("$"))
paramName = item.Substring(0, item.IndexOf("="));
paramValue = item.Substring(item.IndexOf("=") + 1);
ParameterBag.Add(paramName, paramValue);
return ParameterBag;


protected override void OnStartProcessingRequest(ProcessRequestArgs args)
OpsContext = args.OperationContext;
QueryParameters = GetQueryParameterBag(OpsContext);
logger.Log(LogLevels.Medium, String.Format("OnStartProcessingRequest: {0}", OpsContext.AbsoluteRequestUri));

oData interception

Once we have intercepted the WCF call we can use the information in the more specific calls.
In our case we have one entity “customer” that we would like to alter

// Expose IQueryable properties as read-only Atom collections
public class CustomerDataService : DataService


        public IQueryable Customers()
logger.Log(LogLevels.Medium, String.Format("IQueryable Customers called"));
return this.CurrentDataSource.Customers;

Start the Data Service

public void Start()

logger.Log(LogLevels.Information, "[Stating DataServiceTest] ****** ");
logger.Log(LogLevels.Information, "");

string serviceAddress = "http://localhost:998";
Uri[] uriArray = { new Uri(serviceAddress) };
Type serviceType = typeof(CustomerDataService);

using (var host = new DataServiceHost(serviceType, uriArray))

logger.Log(LogLevels.Information, "Press any key to stop service");


Service Logging

It can be interesting to show some logging. The following is from msdn WCF (Ref [1])

// svcDesc is a ServiceDescription.
var svcDesc = host.Description;
string configName = svcDesc.ConfigurationName;
logger.Log(LogLevels.Information, String.Format("Configuration name: {0}", configName));

// Iterate through the endpoints contained in the ServiceDescription
ServiceEndpointCollection sec = svcDesc.Endpoints;
foreach (ServiceEndpoint se in sec)
logger.Log(LogLevels.Information, "Endpoint:");
logger.Log(LogLevels.Information, String.Format("\tAddress: {0}", se.Address.ToString()));
logger.Log(LogLevels.Information, String.Format("\tBinding: {0}", se.Binding.ToString()));
logger.Log(LogLevels.Information, String.Format("\tContract: {0}", se.Contract.ToString()));
KeyedByTypeCollection behaviors = se.Behaviors;
foreach (IEndpointBehavior behavior in behaviors)
logger.Log(LogLevels.Information, String.Format("Behavior: {0}", behavior.ToString()));

string name = svcDesc.Name;
logger.Log(LogLevels.Information, String.Format("Service Description name: {0}", name));

string namespc = svcDesc.Namespace;
logger.Log(LogLevels.Information, String.Format("Service Description namespace: {0}", namespc));

Type serviceType2 = svcDesc.ServiceType;
logger.Log(LogLevels.Information, String.Format("Service Type: {0}", serviceType2.ToString()));

// The service can now be accessed.
logger.Log(LogLevels.Information, "The service is ready.");

Service Queries

Now let’s start the service and check the results

Service MetaData




Query all customers




Query only one customer





[1] http://msdn.microsoft.com/en-us/library/system.servicemodel.description.servicedescription(v=vs.90).aspx
Recomended article on DataServices
[2] http://www.codeproject.com/Articles/514598/Understanding-OData-v3-and-WCF-Data-Services-5-x
[3] http://www.codeproject.com/Articles/393623/OData-Services


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 )

Google+ photo

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

Twitter picture

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

Facebook photo

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


Connecting to %s

Tag Cloud

%d bloggers like this: