Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate URL of a versioned API action with IUrlHelper

In my ASP.NET Core project I'm using aspnet-api-versioning like so:

[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/users")]
[Authorize]
public class UserController : Controller
{

  [HttpGet, MapToApiVersion("1.0")]
  public async Task<IActionResult> GetUsers([FromQuery] string searchString, [FromQuery] bool allOrganizations = false)
  {
   ...
  }

}    

So the request is sent to: GET /api/v1/users.

When adding another version of this action I would just add the attribute MapToApiVersion("2.0") so it would be GET /api/v2/users. That's all fine.

However in a view I call this action with ajax like so:

$.ajax({
url: '@Url.Action("GetUsers", "User", new{version = 1})' + "?searchString=" + $("#user-search").val() + "&allOrganizations=true",
type: "GET",
success: function(data) {
response($.map(data,
function(obj) {
return {
        //some mapping
       };
 }));
}
});

This calls the endpoint:/User/GetUsers?version=1?searchString={searchString}&allOrganizations=true

So it appends the version as a query parameter instead of route parameter.

If I don't add the new {version = 1} it's the same just without the 'version' query parameter.

I've also tried using @Url.RouteUrl("Get_Users", new {version =1}) and naming the action with [HttpGet("Get_Users"), MapToApiVersion("1.0")] but that just appends the query parameters to the current url.

However if I change the Controllers route attribute from [Route("api/v{version:apiVersion}/users")] to [Route("api/users")] and ommit the version parameter, the ajax call works fine.

So is there any way to use IUrlHelper (or some other way) to get the correct route to a versioned action besides hardcoding the url string? Or am I doing versioning wrong in some way?

I may just be complicating here, but I still think this should work, no?

like image 570
erikbozic Avatar asked Sep 03 '25 15:09

erikbozic


1 Answers

I appreciate this answer is not .net core specific and may not answer you question, but consider creating api controllers with the version in the name of the controller

e.g. V1Controller, V2Controller so the Urls /api/v1/GetUsers, /api/v2/GetUsers this handles versioning and keeps the code discreet between versions and reduces any method name conflicts.

like image 128
Mark Redman Avatar answered Sep 05 '25 05:09

Mark Redman