15

I have an ASP.NET Core with the following controller that accepts a POST request:

[Route("api/v1/tenants/tests")]
public class TestsController : Controller
{
    [HttpPost]       
    public IActionResult Post(string tenantId)
    {
        return Ok();
    }
}

I have developed a 'null' middleware to test things out. It is defined in the Configure method of the Startup.cs file:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
     if (env.IsDevelopment())
     {
         app.UseDeveloperExceptionPage();
     }

     app.UseMvc();

     app.Use(async (context, next) =>
     {
         // Forward to the next one.
         await next.Invoke();
     });
}

Question

When I call the controller via Postman, the initial call to the POST method goes successfully through the middleware and then to the Controller. However, the following calls directly go to the Controller, skipping the middleware entirely. Why is that?

Kzryzstof
  • 7,688
  • 10
  • 61
  • 108

2 Answers2

23

The middlewares must be set up before calling app.UseMvc().

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
     if (env.IsDevelopment())
     {
         app.UseDeveloperExceptionPage();
     }

     app.Use(async (context, next) =>
     {
         // Forward to the next one.
         await next.Invoke();
     });

     // !! Have to be called after setting up middleware !!
     app.UseMvc();
}

This information is present in the documentation but I was not aware that it was applicable to custom middlewares as well:

The order that middleware components are added in the Startup.Configure method defines the order in which the middleware components are invoked on requests and the reverse order for the response. The order is critical for security, performance, and functionality.

The following Startup.Configure method adds middleware components for common app scenarios:

1 - Exception/error handling

2 - HTTP Strict Transport Security Protocol

3 - HTTPS redirection

4 - Static file server

5 - Cookie policy enforcement

6 - Authentication

7 - Session

8 - MVC

Update

In ASP.Net Core 3.0, you need to add your middleware before MapControllers()

 app.UseEndpoints(endpoints =>
 {
     endpoints.MapControllers();
 });
Kzryzstof
  • 7,688
  • 10
  • 61
  • 108
3

Startup.Configure() is executed once during app startup. It is used to make preparations for the application, it is not executed with every call. You can however use it to setup a middleware that is executed with every call. The microsoft documentation for asp.net core application startup contains a few examples both Configure and ConfigureServices.

Dirk Trilsbeek
  • 5,873
  • 2
  • 25
  • 23
  • 2
    I am not sure you understood the question. I understand that Configure() is called once, so is the setup of the middleware. However I think the middleware should be executed at every requests, like specified in the documentation... I have edited the question to make things hopefully clearer. – Kzryzstof Oct 02 '18 at 16:50
  • 2
    I've created a new test project (ASP.Net Core 2.1, with VS 2017 15.8.5), pasted your null middleware into the Configure() method and tested it with IIS express, the middleware is called every time. I added a form to the default index page, a post action that just redirects to Index into the controller and upon pushing the post button the middleware was again called every time. I then changed the controller return value to just Ok() and tested again, again the middleware was executed every time after reloading the index page and pushing the button. – Dirk Trilsbeek Oct 02 '18 at 17:11
  • I have created a similar test (ASP.NET Core 2.1 and VS15.8.3) and only the first call is passing through the middleware... I just do not understand. – Kzryzstof Oct 02 '18 at 17:30
  • 2
    I found it. While moving stuff around, I ended up putting UseMvc at the end of the Configure method, leaving the middleware setup before. And it works now. Like Ross Geller said in Friends, "Well, they should put it in hugggee black letters!" – Kzryzstof Oct 02 '18 at 17:37