2

I am currently developing an OData service using Web Api 2 and EF6 with a Code First Approach. My controllers inherit from the normal ApiController Base.

I have decorated my action methods with the Queryable attribute and have also enabled Query Support in the WebApiConfig file. Through my CORS policy, I have specified the DataServiceVersion and MaxDataServiceVersion as part of my Accept and Exposed Headers.

Strangely, my odata endpoint seems to not return the DataServiceVersion as part of the response header but, if my controllers inherit from the ODataController base I am able to see it in the response.

Is there a way to enable this header while using ApiController as the base.

This header is needed as datajs requires it on the client side.

chirag kalyanpur
  • 122
  • 1
  • 10

1 Answers1

2

First to answer your question: Yes, you can expose the DataServiceVersion http header yourself. It's custom code though, not a setting on an existing component.

Add a "Filter" to your global http configuration. A filter is a class derived from "System.Web.Http.Filters.ActionFilterAttribute".

for example;

internal class DataServiceVersionHeaderFilterWebAPI : System.Web.Http.Filters.ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        actionExecutedContext.Response.Content.Headers.Add("DataServiceVersion", "3.0");
        actionExecutedContext.Response.Content.Headers.Add("Access-Control-Expose-Headers", "DataServiceVersion");
    }
}

Then configure this filter to be used (in application start of global.asax)

GlobalConfiguration.Configuration.Filters.Add( new DataServiceVersionHeaderFilterWebAPI() );

This will allow your cross domain OData query from a security perspective. There is however another issue with this;

OData is a specification larger than just the request URI's & HTTP headers. It also specifies how to exchange model information and the actual data exchange is a predefined object structure. Simple, but still a predefined structure.

object.d = service returned content

You will have to implement all those pieces of the specification ($filter,$metadata,$top, return formats, etc) yourself.

Some food for thought.

Marvin Smit
  • 4,088
  • 1
  • 22
  • 21
  • While using breeze on my client, I was trying to query my Odata endpoint which was using an ApiController. The query to the service would succeed but the results were being returned in my promise's failure handler. Zeroing in on the issue, I came to understand that yes sending the DataServiceVersion does not work as you mentioned above. Likewise, controllers inherited from the OdataController/ EntitySetController appeared to do the trick; the output was being returned to the success handler. I had to modify the Cors policy to expose dataservice and maxdataservice versions though. – chirag kalyanpur Sep 05 '14 at 21:30