Aspnet-api-versioning: Adding Api Version in RoutePrefix -- No route providing a controller name with API version '2' was found to match request URI

Created on 3 Apr 2017  路  7Comments  路  Source: microsoft/aspnet-api-versioning

Hi,

I implemented this package in api and after that I am getting this error:

No route providing a controller name with API version '2' was found to match request URI 'http://localhost:52477/api/V2/path'

Please note that, code is working if I use 'http://localhost:52477/api/path?api-version=1.0' or 'http://localhost:52477/api/path?api-version=2.0'.

WebApiConfig code:

// added to the web api configuration in the application setup
var constraintResolver = new DefaultInlineConstraintResolver()
{
ConstraintMap =
{
["apiVersion"] = typeof( ApiVersionRouteConstraint )
}
};

        config.MapHttpAttributeRoutes(constraintResolver);
        // allow a client to call you without specifying an api version
        // since we haven't configured it otherwise, the assumed api version will be 1.0
        config.AddApiVersioning(o => o.AssumeDefaultVersionWhenUnspecified = true);

        config.Routes.MapHttpRoute(
           name: "DefaultApi",
           routeTemplate: "api/{controller}/{id}",
           defaults: new { id = RouteParameter.Optional }
       );

I am using RoutePrefix to add version to the route:

[ApiVersion("1.0")]
[RoutePrefix("api/v{version:apiVersion}/Home")]
public class HomeController : ApiController
{
--code here--
}
[ApiVersion("2.0")]
[RoutePrefix("api/v{version:apiVersion}/Home")]
public class HomeControllerV2 : ApiController
{
--code here--
}

Please do help. I am stuck here.

answered question

Most helpful comment

So right! Der! @_@

However, you _should_ be able to do this:

```c#
[ApiVersion("1.0")]
[RoutePrefix("api")]
public class HomeController : ApiController
{
// ~/api/home
// ~/api/v1/home
[Route( "Home" )]
[Route( "v{version:apiVersion}/Home" )]
public IHttpActionResult Get() => Ok();
}

[ApiVersion("2.0")]
[RoutePrefix("api")]
public class HomeV2Controller : ApiController
{
// ~/api/v2/home
[Route( "v{version:apiVersion}/Home" )]
public IHttpActionResult Get() => Ok();
}
```

Interesting SO link. I haven't seen that ever mentioned before. Good to know. You might want to review #73 where this topic was discussed quite a bit in-depth. There are a couple of working solutions there.

All 7 comments

@commonsensesoftware Can you please check it asap

Succinctly, I will just say that this is not a supported scenario. If you search through the issues, this topic has been discussed before. I'll make it a point to add something to the wiki that discusses this perceived limitation.

The issue has more to do with how routing and, frankly REST, work. Remember that the URL path is the resource identifier. When you version using a URL segment, there is no way to implicitly match anything. You wouldn't expect api/home to implicitly match api/home/1. I'm not much of a fan of this versioning approach because it makes your URLs vary overtime; however, it's popular in the wild, which is why it's supported.

The only way I know to make your scenario work is to register overlapping routes for the implicit, default version. For example:

```c#
// ~/api/home
// ~/api/v1/home
[ApiVersion("1.0")]
[RoutePrefix("api/Home")]
[RoutePrefix("api/v{version:apiVersion}/Home")]
public class HomeController : ApiController { }

// ~/api/v2/home
[ApiVersion("2.0")]
[RoutePrefix("api/v{version:apiVersion}/Home")]
public class HomeV2Controller : ApiController
```

In order to shift where the default API version is defined, you'd have to move the attribute declarations. It's not exactly painless to make this change, but if you're not shifting around your default API version often, then it shouldn't be a huge deal.

Since you're using Web API, there was someone in the community that created a custom IDirectRouteProvider (aka _attribute routing_) to generate the necessary routes on the fly (I forget which issue it was). This option is certainly open to you. Out-of-the-box support for that approach is something that I might consider in the future, provided that I'm able to implement feature parity between the platforms.

As an aside, it appears that you have attribute and convention-based routes defined. For your own sanity, I recommend choosing one or the other. It will make it much easier to reason about routing issues. When it comes to API versioning, there are some known limitations when to mix them both. This has to do with intrinsic limitations in Web API's routing infrastructure. This is currently documented on the wiki.

I hope that helps.

@commonsensesoftware Thanks for quick response. We can not add multiple RoutePrefixes in ASPNET WebApi. So I will try to manually override all Routes as mentioned in this link. http://stackoverflow.com/questions/24953660/asp-net-web-api-multiple-routeprefix

I will check attribute routing as well.

So right! Der! @_@

However, you _should_ be able to do this:

```c#
[ApiVersion("1.0")]
[RoutePrefix("api")]
public class HomeController : ApiController
{
// ~/api/home
// ~/api/v1/home
[Route( "Home" )]
[Route( "v{version:apiVersion}/Home" )]
public IHttpActionResult Get() => Ok();
}

[ApiVersion("2.0")]
[RoutePrefix("api")]
public class HomeV2Controller : ApiController
{
// ~/api/v2/home
[Route( "v{version:apiVersion}/Home" )]
public IHttpActionResult Get() => Ok();
}
```

Interesting SO link. I haven't seen that ever mentioned before. Good to know. You might want to review #73 where this topic was discussed quite a bit in-depth. There are a couple of working solutions there.

I was checking the link: https://github.com/Microsoft/aspnet-api-versioning/issues/73 and I found link to sample for swagger versioning update : https://github.com/Microsoft/aspnet-api-versioning/tree/dev/chrimart/implement-api-explorer/samples/webapi/SwaggerWebApiSample
I did the same but I am getting error in 2 places:

Startup.cs
var apiExplorer = configuration.AddVersionedApiExplorer();

ImplicitApiVersionParameter.cs
var description = apiDescription as VersionedApiDescription;

It is not able to find AddVersionedApiExplorer() method under HttpConfiguration and type VersionedApiDescription is coming as undefined.

Please guide on what is missing. I am using .net framework 4.6.1

This code is in the branch that I'm currently working on. It hasn't been released in any form - yet. Daytime job aside, I may have a beta version of the packages released later this week. I've been sharing the link to the code under development for folks to comment on and provide feedback.

I updated the wiki to address this topic in the future.

The first iteration of packages to support Swagger are available. I'm leaving a little burn-in time with a beta release for issues and/or feedback before the official release. I'll be updating the wiki soon.

Was this page helpful?
0 / 5 - 0 ratings