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