Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 需要版本控制的asp net核心中间件_C#_Asp.net Core_Asp.net Core Mvc_Middleware_Api Versioning - Fatal编程技术网

C# 需要版本控制的asp net核心中间件

C# 需要版本控制的asp net核心中间件,c#,asp.net-core,asp.net-core-mvc,middleware,api-versioning,C#,Asp.net Core,Asp.net Core Mvc,Middleware,Api Versioning,我有一个带有API版本控制的MVC net core 2.2应用程序。我只希望中间件运行在2版或更高版本的api上 我编写的中间件类使用了IApiVersionReader.Read(),但是在Startup中的UseMVC行之后,才会填充该类 var apiVersion = _apiVersionReader.Read(_httpContextAccessor.HttpContext.Request); 因此,如果我在UseMVC之前注册中间件,那么它就无法使用版本控制方法读取版本 但是如

我有一个带有API版本控制的MVC net core 2.2应用程序。我只希望中间件运行在2版或更高版本的api上

我编写的中间件类使用了
IApiVersionReader.Read()
,但是在
Startup
中的
UseMVC
行之后,才会填充该类

var apiVersion = _apiVersionReader.Read(_httpContextAccessor.HttpContext.Request);
因此,如果我在
UseMVC
之前注册中间件,那么它就无法使用版本控制方法读取版本

但是如果我将中间件放在
UseMVC
行之后,那么它根本不会触发

这感觉像是鸡和蛋的情况!我怎样才能让它工作

为了简单起见,这里有一个我创业的简化版本

public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(config =>
            {
                // Don't add auth in development.        
                if (!CurrentEnvironment.IsDevelopment())
                {
                    var policy = new AuthorizationPolicyBuilder()
                        .RequireAuthenticatedUser()
                        .Build();
                    config.Filters.Add(new AuthorizeFilter(policy));
                }
            }
        );

        services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();

        services.AddMvcCore()
            .AddAuthorization()
            .AddJsonFormatters(config =>
                config.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);

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

    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {

        app.UseMvc();

        app.UseMiddleware(typeof(UserDataLoggingMiddleware));
    }
public void配置服务(IServiceCollection服务)
{
services.AddMvc(配置=>
{
//不要在开发中添加auth。
如果(!CurrentEnvironment.IsDevelopment())
{
var policy=new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()文件
.Build();
config.Filters.Add(新的授权过滤器(策略));
}
}
);
services.AddTransient();
services.AddMvcCore()
.AddAuthorization()
.AddJsonFormatters(配置=>
config.ReferenceLoopHandling=ReferenceLoopHandling.Ignore);
services.addapVersioning(选项=>
{
options.ReportApiVersions=true;
options.AssumeDefaultVersionWhenUnspecified=true;
options.DefaultApiVersion=新的ApiVersion(2,0);
});
}
公共无效配置(IApplicationBuilder应用程序,IHostingEnvironment环境)
{
app.UseMvc();
app.useMidleware(typeof(UserDataLoggingMiddleware));
}

我可以在这里想出几个选择

  • 您可以通过
    \u httpContextAccessor.HttpContext.Request.Path
    手动获取URL中的版本,或者如果其位于标题中,则
    \u httpContextAccessor.HttpContext.Request.headers

  • 注册中间件时使用
    UseWhen
    。这将配置中间件管道。你想要的是一个重新加入的分支机构。有关分支中间件的更多信息,请参阅本文->


  • 在Github页面上得到响应

    API版本控制自动注册它的中间件纯粹是为了简单。要自己控制行为,请执行以下操作:

    首先,选择退出自动注册:

    services.AddApiVersioning(options => options.RegisterMiddleware = false);
    
    然后,在管道中以您喜欢的方式注册中间件:

    services.UseApiVersioning();
    services.UseMvc();
    

    我希望这会有所帮助。

    这是正确的设置;但是,值得注意的是,中间件所做的唯一一件事就是将IApiVersioningFeature注册到当前的HttpContext中。请注意,关于当前请求的API版本的最终决定尚未解决。在中间件中实现这一点并不容易。IApiVersioningFeature将通过IApiVersionReader获得原始和解析的API版本,但要知道解析API版本可能是
    null
    (例如:它无效)或可能不存在。在中间件实现中需要考虑这一点。