1

这个想法是通过 URL 拥有一个版本化的 API,如下所示:

  • /api/v1/天气预报
  • /api/v2/天气预报
  • /api/v3/天气预报

我的命名空间如下:

命名空间版本控制

在启动时我有这个代码来注册版本控制:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddApiVersioning(
        options =>
        {
            // reporting api versions will return the headers "api-supported-versions" and "api-deprecated-versions"
            options.ReportApiVersions = true;
            // automatically applies an api version based on the name of the defining controller's namespace
            options.Conventions.Add(new VersionByNamespaceConvention());
        });
}

所以我想删除每个控制器中的“[Route("api/v{version:apiVersion}/[controller]")]"属性这可能吗?

我试图使用这样的东西来映射控制器:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseAuthorization();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "api",
            pattern: "api/v{version:apiVersion}/{controller}/{id?}"
            );
    });
}

但是当我运行代码时,它给出了以下错误:

操作“ApiVersioning.Api.V3.Controllers.WeatherForecastController.Get (ApiVersioning)”没有属性路由。使用 ApiControllerAttribute 注释的控制器上的操作方法必须是属性路由。

那么我可以为所有控制器添加一个隐式路由约定,从而消除对每个控制器顶部的 RouteAttribute 的需要吗?

4

1 回答 1

0

您看到的错误消息是内置 API Explorer 的限制。它只支持属性路由。如果您不需要它作为文档,那么它应该不是问题。

与旧的 ASP.NET 不同, UI 控制器API 控制器之间没有区别。但是,开发人员期望它们之间存在某些行为。API 版本控制要求所有控制器都进行版本控制,即使是通过默认 API 版本隐式进行的(否则未修饰)。对于那些将 UI 和 API 混合在一起的人来说,这种行为是不可取的。引入[ApiController]属性后,终于有一种方法可以可靠地识别控制器是否用于 API。

要对此进行测试,您只需更改ApiVersioningOptions.UseApiBehavior = false. 这将恢复到旧的行为。请记住,这将导致所有控制器都被版本化。

另一种方法是实现IApiControllerSpecificationIApiControllerFilter。通常你只需要IApiControllerSpecification因为过滤器是所有规范的聚合。使用 DI 容器注册您的规格或过滤器。规范的实现决定了控制器是否适用于给定ControllerModel的 API 。有一个内置规范可以查找[ApiController]. 您可以创建一个查找ControllerBase作为基类或使用其他一些机制,例如路由模板中的前缀或包含命名空间。这个选择由你。该规范将允许您使用自己的约定,而不必使用[ApiController].

您还可以在一个地方为所有具有所需属性的控制器使用基类。它与使用标准路由约定并不完全相同,但会达到类似的结果。如果您希望支持 API 文档,您可能需要这种方法。

于 2020-09-16T21:21:48.207 回答