在我的ASP.NET核心项目中,我正在使用aspnet-api-versioning,如下所示:
[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)
{
...
}
}
因此请求将发送至:GET /api/v1/users
。
添加此操作的其他版本时,我只需添加属性MapToApiVersion("2.0")
,使其为GET /api/v2/users
。
这一切都很好。
但是在视图中我用ajax这样调用这个动作:
$.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
};
}));
}
});
这会调用端点:/User/GetUsers?version=1?searchString={searchString}&allOrganizations=true
因此它将版本作为查询参数而不是路由参数附加。
如果我不添加new {version = 1}
,那么只是没有'version'查询参数。
我还尝试使用@Url.RouteUrl("Get_Users", new {version =1})
并将操作命名为[HttpGet("Get_Users"), MapToApiVersion("1.0")]
,但只是将查询参数附加到当前网址。
但是,如果我将控制器路由属性从[Route("api/v{version:apiVersion}/users")]
更改为[Route("api/users")]
并省略version参数,则ajax调用可以正常工作。
除了硬编码url字符串之外,还有什么方法可以使用IUrlHelper
(或其他方式)获取版本化操作的正确路由?或者我在某种程度上做版本错误?
我可能只是在这里变得复杂,但我仍然认为这应该有效,不是吗?
答案 0 :(得分:1)
我很欣赏这个答案不是.net核心特定的,可能不会回答你的问题,但考虑用控制器名称中的版本创建api控制器
e.g。 V1Controller,V2Controller,因此Urls / api / v1 / GetUsers,/ api / v2 / GetUsers可以处理版本控制并在版本之间保持代码谨慎,并减少任何方法名称冲突。
答案 1 :(得分:1)
不幸的是, IUrlHelper 不支持API版本。我建议使用版本化名称(例如[HttpGet(Name = "GetUsersV1")]
)命名您需要解析的路线,然后使用Url.Link( "GetByUsersV1", new { version = 1 } )
。
答案 2 :(得分:0)
(让我烦恼)的解决方案是将确切的API version
值作为字符串值而不是像整数那样传递。因此,在您的剃须刀摘录中,IUrlHelper
实例应按以下方式调用:
url: '@Url.Action("GetUsers", "User", new { version = "1.0" })' ...
请注意,该版本明确为1.0,该版本正确地(如MAJOR.MINOR这样的语法)与您在属性中指定的版本[ApiVersion("1.0")]
相匹配。