I'm trying to implement both Attribute Routing and the VersionedRoute
from RoutingConstaints Sample but when I use both on a controller, the versioned attribute no longer works.
What would I need to modify on the attribute to get it to play nice with Attribute Routing?
For code example download the sample project (or just look at the few files from the above link) and then modify the routes as such:
// When I use the RoutePrefix, VersionedRoute no longer works (Sending "Api-Version" through http header doesn't route correctly
// If I remove the RoutePrefix I can use VersionedRoute again
// What do I need to change in its code to be able to use both?
[VersionedRoute("api/Customers", 1)] // This route would be used as http://url/api/customers with a header of "api-version: 1"
[RoutePrefix("api/v1/Customers")] // This route would be used purely through url versioning of http://url/api/v1/Customers
public class CustomersV1Controller : ApiController {
/* Other stuff removed */
[VersionedRoute("api/Customer", 1)] // I'd rather not have to use this here at all and just use a single one on the class, but having both nor just one on either works right now.
[Route("")]
public IHttpActionResult Get()
{
return Json(_customers);
}
}
Edit: Please let me know if you need more information or even post ideas or things to try :)
Edit2: Here is an example of what I'm trying to do from Troy Hunt's Blog: http://www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html
Edit3: Here is what I'd like to code to be as close to since it would reduce a lot of the overhead and magic strings.
[VersionedRoute("api/Customers", 1)] // This route would be used as http://url/api/customers with a header of "api-version: 1"
[RoutePrefix("api/v1/Customers")] // This route would be used purely through url versioning of http://url/api/v1/Customers
public class CustomersV1Controller : ApiController {
/* Other stuff removed */
[Route("")]
public IHttpActionResult Get()
{
// Removed
return Ok(customers);
}
[Route("{id:int}")]
public IHttpActionResult GetById(int id)
{
// Removed
return Ok(customer);
}
}
[VersionedRoute("api/Customers", 2)] // This route would be used as http://url/api/customers with a header of "api-version: 2"
[RoutePrefix("api/v2/Customers")] // This route would be used purely through url versioning of http://url/api/v2/Customers
public class CustomersV2Controller : ApiController {
/* Other stuff removed */
[Route("")]
public IHttpActionResult Get()
{
// Removed
return Ok(customersThatAreDifferentThanV1);
}
[Route("{id:int}")]
public IHttpActionResult GetById(int id)
{
// Removed
return Ok(customerThatIsDifferent);
}
}
Edit: Last bump, trying to only have to write the route version information once per route, at the controller attribute level and not per-action.
VersionedRoute("Customer", 1)
which would allow me to use http headers to supply the version #, as well as using aRoutePrefix("v1/Customer/")
for versioning through the url. Basically I want to support both header and url versioning. However when I apply theRoutePrefix
theVersionedRoute
attribute stops working. - JohnRoute
but notRoutePrefix
but there's someone in the comments with what looks like a potential solution. - DavidG