skip to Main Content
  1. I have created a middleware using app.Map() that handles a specific route (/hello).
  2. However, when I add a second middleware using app.Run() that does not check for a specific route.
  3. It seems to overwrite the response of the first middleware even when a request is made to the /hello route.

I’m confused about why this is happening and how to fix it.

The code is below:

using Microsoft.Extensions.Primitives;
using System.Web;

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.Map("/hello", async (HttpContext context) => {

    context.Response.ContentType = "text/html";

    await context.Response.WriteAsync("Hello");
});

app.Run(async (HttpContext context) => {

    context.Response.ContentType = "text/html";

    await context.Response.WriteAsync("Bye");

});

app.Run();

I tried removing the app.Run() middleware then the specified ‘/hello’ middleware is executing.
But as soon as I add the app.Run() middleware again it then skips the middleware that is mapped to ‘/hello’;

2

Answers


  1. Try switching to Use:

    app.Use(async (HttpContext context, Func<Task> next) =>
    {
        await next();
    
        if (!context.Response.HasStarted)
        {
            context.Response.ContentType = "text/html";
    
            await context.Response.WriteAsync("Bye");
        }
    });
    app.Map("/hello", async (HttpContext context) => {
        context.Response.ContentType = "text/html";
    
        await context.Response.WriteAsync("Hello");
    });
    
    app.Run();
    

    I guess that the behaviour is due to the fact that the RunExtensions.Run adds something called "terminal middleware delegate".

    Also ASP.NET Core Middleware article can be useful.

    Login or Signup to reply.
  2. You could check the source codes of RunExtensions.Run() method here

    public static class RunExtensions
    {
        /// <summary>
        /// Adds a terminal middleware delegate to the application's request pipeline.
        /// </summary>
        /// <param name="app">The <see cref="IApplicationBuilder"/> instance.</param>
        /// <param name="handler">A delegate that handles the request.</param>
        public static void Run(this IApplicationBuilder app, RequestDelegate handler)
        {
            ArgumentNullException.ThrowIfNull(app);
            ArgumentNullException.ThrowIfNull(handler);
    
            app.Use(_ => handler);
        }
    }
    

    it adds a middleware like

    app.Use(next => async (HttpContext context) =>
    {
        context.Response.ContentType = "text/html";
    
        await context.Response.WriteAsync("Bye");
    
    });
    

    if you don’t branch the pipeline ,your request would be shortcut

    You could try with Guru Stron’s solution or

    app.MapFallback(async (HttpContext context) =>
    {
        context.Response.ContentType = "text/html";
    
        await context.Response.WriteAsync("Bye");
    });
    

    Or branch the pipeline:

    app.Map("/hello",app=>app.Run(async (HttpContext context) =>
    {
    
        context.Response.ContentType = "text/html";
    
        await context.Response.WriteAsync("Hello");
    }));
    

    For your requirement

    You could check the difference:
    enter image description here
    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search