Search code examples
c#asp.net-coreasp.net-core-mvcmiddlewareapi-versioning

asp net core Middleware that needs apiversioning version


I have an MVC net core 2.2 application with API Versioning. I only want the middleware to run for v2 of the api or greater.

The middleware class I have written uses the IApiVersionReader.Read(), however that doesn't seem to be populated until after the UseMVC line in Startup.

var apiVersion = _apiVersionReader.Read(_httpContextAccessor.HttpContext.Request);

So if I register my middleware before UseMVC, then it can't read the version using the versioning method.

But if I put my middleware after the UseMVC line, then it doesn't trigger at all.

It feels like a chicken and egg situation! How can I get this to work?

Here's a simplified version of my startup, for brevity.

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));
    }

Solution

  • Got a response on the Github page.

    API Versioning auto-registers it's middleware purely for simplicity. To control the behavior yourself, do the following:

    First, opt out of auto-registration:

    services.AddApiVersioning(options => options.RegisterMiddleware = false);
    

    Then, register the middleware however you like in the pipeline:

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

    I hope that helps.