Marty
Marty

Reputation: 3555

webApi2 Odata v3 and V4 side by side

How can I have odata v3 and v4 api working side by side out on the same project ?

Can the same controller be returning data in both formats ? Do I need to have 2 copies of the same controller - one per Odata version ?

I know this should be possible cause the official WEBAPI page says it's been designed for.

"ASP.NET Web API supports both v3 and v4 of the protocol. You can even have a v4 endpoint that runs side-by-side with a v3 endpoint." - quote from www.asp.net

Question is - how do I do that ? Any tutorials ?

Upvotes: 9

Views: 5989

Answers (4)

Jeff Dunlop
Jeff Dunlop

Reputation: 893

To summarize the steps which are quite simple without having to download a sample, nuget Microsoft.AspNet.WebApi.Odata for v3, and Microsoft.AspNet.OData for v4. Starting with v3 and v4 wired up with default conventions, you'll get a duplicate controller name found. From here, change your v3 default route prefix to "odata/v3" (not required but recommended), and for v4, set the default route prefix to "odata/v4" and rename your controller to MyEntityV4Controller. At this point, attempting to use route attributes to solve the error will lead to an http 406 result. Instead, create a class:

public class CustomControllerRoutingConvention : IODataRoutingConvention
{
    public string SelectAction(ODataPath odataPath, HttpControllerContext controllerContext, ILookup<string, HttpActionDescriptor> actionMap)
    {
        return null;
    }

    public string SelectController(ODataPath odataPath, HttpRequestMessage request)
    {
        if (odataPath.EdmType == null)
            return null;
        var path = odataPath.Segments.OfType<EntitySetPathSegment>().SingleOrDefault();
        if (path == null)
        {
            return null;
        }
        return path.EntitySetName + "V4";
    }
}

And use it as so:

config.MapODataServiceRoute(
            "odatav4",
            "odata/v4",
            builder.GetEdmModel(),
            new DefaultODataPathHandler(),
            routingConventions);

From here you'll be able to browse to odata/v3/MyEntitys and odata/v4/MyEntitys, etc.

Upvotes: 0

maomao
maomao

Reputation: 221

Yes, you do need two set of controllers. V4 doesn't provide backward compatibility.

There is also another sample for versioning: https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataVersioningSample/

This is the right solution for you. You make the first version (~/api/v1/) for OData V3 and the second version (~api/v2/) for V4. It provides better separation.

Upvotes: 4

CodingWithSpike
CodingWithSpike

Reputation: 43718

It depends a bit on the OData implementation. I know WCF supports the OData-Version header:

http://docs.oasis-open.org/odata/odata/v4.0/os/part1-protocol/odata-v4.0-os-part1-protocol.html#_Toc372793615

that the client can use to specify the version that it wants, and WCF will act appropriately with just 1 endpoint.

WebAPI on the other hand, I do not know about, but it is probably worth testing.

Upvotes: 0

Tan Jinfu
Tan Jinfu

Reputation: 3347

Here is a sample for side by side: https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/ODataSxSSample/, FYI. This sample has 2 copies of the same controller.

Upvotes: 4

Related Questions