Search code examples
asp.net-web-apiodataasp.net-web-api2datajs

DataServiceVersion header missing in the Http response


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.


Solution

  • 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.