.NET API Versioning: How to use default version only when unspecified, not when requested version is invalid

huangapple go评论52阅读模式
英文:

.NET API Versioning: How to use default version only when unspecified, not when requested version is invalid

问题

I'm building a .NET 6 API Service with versioning via Content-/Accept-Header (with Microsoft.AspNetCore.Mvc.Versioning). I want the following behaviour to work:

  1. If no version is specified via the HTTP-request-header, a default version shall be assumed.
  2. If an unsupported version is specified via the HTTP-header, the service shall return with an error code (e.g. UnsupportedMediaType).

Let's say my service supports versions 1.0 and 2.0 with 2.0 as default:

Content-Type application/json;v=1.0` --> use version 1.0
Content-Type application/json;v=2.0` --> use version 2.0
Content-Type application/json`       --> use version 2.0
Content-Type application/json;v=3.0` --> error

I tried using the AssumeDefaultVersionWhenUnspecified Parameter:

    services.AddApiVersioning(opt =>
    {
        opt.DefaultApiVersion = new ApiVersion(2, 0);
        opt.AssumeDefaultVersionWhenUnspecified = true;
    });

But that leads to every unsupported version being also considered "unspecified", so the last case results in:

Content-Type application/json;v=3.0` --> version 2.0

Does anyone know how I can achieve the desired behaviour?

英文:

I'm building a .NET 6 API Service with versioning via Content-/Accept-Header (with Microsoft.AspNetCore.Mvc.Versioning). I want the following behaviour to work:

  1. If no version is specified via the HTTP-request-header, a default version shall be assumed.
  2. If an unsupported version is specified via the HTTP-header, the service shall return with an error code (e.g. UnsupportedMediaType).

Let's say my service supports versions 1.0 and 2.0 with 2.0 as default:

Content-Type application/json;v=1.0` --> use version 1.0
Content-Type application/json;v=2.0` --> use version 2.0
Content-Type application/json`       --> use version 2.0
Content-Type application/json;v=3.0` --> error

I tried using the AssumeDefaultVersionWhenUnspecified Parameter:

    services.AddApiVersioning( opt =>
    {
        opt.DefaultApiVersion = new ApiVersion( 2, 0 );
        opt.AssumeDefaultVersionWhenUnspecified = true;
    }

But that leads to every unsupported version being also considered "unspecified", so the last case results in:

Content-Type application/json;v=3.0` --> version 2.0

Does anyone know how I can achieve the desired behaviour?

答案1

得分: 1

好的,以下是已翻译的部分:

好的,我认为我找到了一个解决方案,我想要分享给任何人遇到相同问题的人:

services.AddApiVersioning( opt =>
{
    var defaultVersion = new ApiVersion( 2, 0 );
    opt.DefaultApiVersion = defaultVersion;
    opt.AssumeDefaultVersionWhenUnspecified = true;
    opt.ReportApiVersions = true;
    opt.ApiVersionReader = new MediaTypeApiVersionReader();
    opt.ApiVersionSelector = new MyApiVersionSelector( defaultVersion );
} );

.

internal class MyApiVersionSelector : IApiVersionSelector
{
    private readonly ApiVersion defaultVersion;

    public MyApiVersionSelector( ApiVersion defaultVersion )
    {
        this.defaultVersion = defaultVersion;
    }

    public ApiVersion SelectVersion( HttpRequest request, ApiVersionModel model )
    {
        return defaultVersion;
    }
}

设置"AssumeDefaultVersionWhenUnspecified"为true非常重要。只有当未指定版本时,才会调用自定义的VersionSelector。如果指定了不受支持的版本,服务将返回错误。

希望这能帮助某人。
英文:

Ok i think I found a solution, which I want to share if anyone ever encounters the same problem:

services.AddApiVersioning( opt =>
{
    var defaultVersion = new ApiVersion( 2, 0 );
    opt.DefaultApiVersion = defaultVersion;
    opt.AssumeDefaultVersionWhenUnspecified = true;
    opt.ReportApiVersions = true;
    opt.ApiVersionReader = new MediaTypeApiVersionReader();
    opt.ApiVersionSelector = new MyApiVersionSelector( defaultVersion );
} );

.

internal class MyApiVersionSelector : IApiVersionSelector
{
    private readonly ApiVersion defaultVersion;

    public MyApiVersionSelector( ApiVersion defaultVersion )
    {
        this.defaultVersion = defaultVersion;
    }

    public ApiVersion SelectVersion( HttpRequest request, ApiVersionModel model )
    {
        return defaultVersion;
    }
}

It's important to have the "AssumeDefaultVersionWhenUnspecified" set to true. The custom VersionSelector will be called only when no version is specified. If an unsupported version is specified, the services answers with an error.

Hope that helps someone.

huangapple
  • 本文由 发表于 2023年6月19日 20:06:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/76506466.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定