【发布时间】:2018-02-19 10:24:50
【问题描述】:
我对中间件层次结构有疑问。我用一个控制器/动作创建了非常简单的 web api
[Route("api/v1/values")]
public class ValuesController : Controller
{
// GET api/v1/values/5
[HttpGet("{id}")]
public async Task<IActionResult> Get(string id)
{
return await Task.Run<IActionResult>(() =>
{
if (id == "nf")
{
return NotFound();
}
return Ok($"value: {id}");
});
}
}
如果匹配,我将路由配置为使用 Mvc,如果不匹配,则将 Default 写入响应。
app.UseMvc();
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("Default");
});
这很好用,您可以在下面看到示例请求/响应:
/api/v1/values/1 -> 200, Body: "value: 1"
/api/v1/values/nf -> 404
/api/v1/values -> "Default"
很好,但后来我添加了 ApiVersioning,所以控制器看起来像这样:
[ApiVersion("1")]
[Route("api/v{version:apiVersion}/values")]
public class ValuesController : Controller
我添加到启动:services.AddApiVersioning();。它完全破坏了路由,现在对于每个请求,我都会得到响应“默认”,当我删除最后一个应用程序时。使用,路由对于值控制器工作正常,但我没有默认中间件。你知道我如何获得与以前相同的响应,但使用 ApiVersioning 吗?
【问题讨论】:
-
如果您从请求中删除
v1,它会命中您的默认中间件吗?例如/api/values -
如果没有 api 版本控制,是的,它会命中默认中间件;使用 api 版本控制,无论我发送什么请求,它总是会命中默认路由。
-
根据您的设置,这是预期的行为。 API 版本控制有它自己的 catch-all 路由器,它总是插入到 MVC 管道的末尾。如果路由可以匹配,但不匹配,则返回 400。在这种情况下,
api/v1/values是一个已定义的 API,但没有标识符就没有匹配项。这将返回 400。此行为与 ASP.NET Core 路由中的限制有关。它应该在 2.2+ 中得到改进。绝对可以将中间件与 API 版本控制结合或使用。您需要描述您想要实现的目标以获得更好的指导。
标签: asp.net asp.net-core .net-core asp.net-core-webapi api-versioning