简体   繁体   中英

Web API 2 Attribute Routing for API Versioning

I have an ASP.NET Web API 2 application which uses convention-based routing:

[app-url]/v1/[controller]

Now, I want to add another version to the API, and found that attribute routing is the easiest way to achieve what I want. Therefore, I registered the Web API routes in the Application_Start() method as shown below.

GlobalConfiguration.Configure(WebApiConfig.Register);

Additionally, I made sure that the Register() method in the WebApiConfig class only contains the following line:

config.MapHttpAttributeRoutes();

There are two controllers to test the versioning:

/v1/StatusController.cs

[RoutePrefix("v1/status")]
public class StatusController : ApiController
{
    [Route("")]
    public string Get()
    {
        return "V1 - OK";
    }
}

/v2/StatusController.cs

[RoutePrefix("v2/status")]
public class StatusController : ApiController
{
    [Route("")]
    public string Get()
    {
        return "V2 - OK";
    }
}

However, when I navigate to either of the routes shown below, I receive an error.

  1. [app-url]/v1/status
  2. [app-url]/v2/status

SERVER ERROR

404 - File or directory not found.

The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable.

Your approach will not work because ASP.NET Web API uses a so-called Controller Selector to find the respective controller for a given route. This selector however, does not take into account the namespace of a controller, but rather uses its name.

By default, Web API ships with the DefaultHttpControllerSelector and you can find information on its implementation here .

A possible solution to your problem is to implement a custom IHttpControllerSelector and tell Web API to use it instead. For this you can find several examples on the internet.

Instead you can also change your controller names to be unique, eg:

  • StatusV1Controller
  • StatusV2Controller

Instead of using different namespaces, use different controller names (if this works for you). If so, here is about how the code should look like:

/v1/StatusController.cs:

[System.Web.Http.RoutePrefix("v1/status")]
public class StatusController : ApiController
{
    [System.Web.Http.Route("")]
    public string Get()
    {
        return "V1 - OK";
    }
 }

/v2/StatusController.cs:

[System.Web.Http.RoutePrefix("v2/status")]
public class Status2Controller : ApiController
{
    [System.Web.Http.Route("")]
    public string Get()
    {
        return "V2 - OK";
    }
 }

Now you would be able to invoke these 2 different versions by calling the Http Get Method like:

Https://YourUrl.com/v1/status

and:

Https://YourUrl.com/v2/status

Hope this suggested alternative helps. Good luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM