Skip to content

Adding Api Version in RoutePrefix -- No route providing a controller name with API version '2' was found to match request URI #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gopaldogra opened this issue Apr 3, 2017 · 7 comments
Assignees

Comments

@gopaldogra
Copy link

gopaldogra commented Apr 3, 2017

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.

@gopaldogra
Copy link
Author

@commonsensesoftware Can you please check it asap

@commonsensesoftware
Copy link
Collaborator

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:

// ~/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.

@gopaldogra
Copy link
Author

gopaldogra commented Apr 3, 2017

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

@commonsensesoftware
Copy link
Collaborator

So right! Der! @_@

However, you should be able to do this:

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

@gopaldogra
Copy link
Author

I was checking the link: #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

@commonsensesoftware
Copy link
Collaborator

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.

@commonsensesoftware
Copy link
Collaborator

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants