Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Versioning Web API actions in ASP.NET MVC 4

I have an ASP.NET MVC 4 app. I want to use the new Web API feature for learning purposes. I want to learn how to expose the same endpoint, but provide different versions of it. In other words, I want to expose endpoints like the following:

http://mysite/1.0/Products/1
http://mysite/2.0/Products/1

In an attempt to do this, I added an "Api" directory within the default "Controllers" directory. Within the "Api" directory, I have two other directories: "Version1-0" and "Version2-0". Each of those directories has an ApiController named "ProductsController".

I tried to expose the endpoints by adding the following route definition in my WebApiConfig.cs file:

config.Routes.MapHttpRoute(
  name: "1-0Api",
  routeTemplate: "api/1.0/{controller}/{id}",
  defaults: new { id = RouteParameter.Optional }
);

Unfortunately, I can't figure out how to expose actions via the URLs I listed above. What am I doing wrong? Thank you!

like image 765
YUI Developer Avatar asked Dec 21 '12 01:12

YUI Developer


People also ask

Is versioning possible in asp net Web API?

Summary. As the application grows and business need increase, Versioning of the API is one of the difficult and important part of the API as it makes the API backward compatible. We can do Versioning in ASP.NET Web API with URI, QueryString, Custom Headers and Accept Header parameters, etc.

What are the main feature of ASP.NET MVC 4 used by ASP Net Web API?

ASP.NET MVC 4 projects now include Entity Framework 5. One of the great features in Entity Framework 5 is support for database migrations. This feature enables you to easily evolve your database schema using a code-focused migration while preserving the data in the database.


2 Answers

You're probably running into issues because the controllers have the same name. The controller namespace or the folder it's in doesn't matter at all to WebAPI, only the name does. The simplest thing I can think of is to rename your controllers ProductsV1Controller and ProductsV2Controller and set up two routes to point to your controllers:

config.Routes.MapHttpRoute(
    name: "1-0Api",
    routeTemplate: "api/1.0/Products/{id}",
    defaults: new { controller = "ProductsV1", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
    name: "2-0Api",
    routeTemplate: "api/2.0/Products/{id}",
    defaults: new { controller = "ProductsV2", id = RouteParameter.Optional }
);

Of course, this gets messy if you have multiple controllers you want to expose in this way. Let me see if I can't think of something better for you.

like image 94
Youssef Moussaoui Avatar answered Sep 30 '22 15:09

Youssef Moussaoui


Sebastiaan Dammann has, on his blog, described how he did Web API versioning by writing his own implementation of IHttpControllerSelector and supporting interfaces.

http://damsteen.nl/blog/implementing-versioning-in-asp.net-web-api

He's also put the code on github

https://github.com/Sebazzz/SDammann.WebApi.Versioning

And packaged it in NuGet for us! :)

https://nuget.org/packages/SDammann.WebApi.Versioning

While implementing IHttpControllerSelector is certainly (imho) the Right Way to do Web API versioning, I think it would be ideal if he included the ability to version based on the HTTP Accept header (see http://barelyenough.org/blog/2008/05/versioning-rest-web-services/).

Unfortunately my client side is unable to work with the Accept header, so his RouteVersionedControllerSelector is ideal for me.

Edit: Not sure how I missed it, but there is indeed an AcceptHeaderVersionedControllerSelector that can be used to do versioning the ideal way. I'm currently using it on a new project, but it still has some drawbacks

like image 36
mo. Avatar answered Sep 30 '22 13:09

mo.