2

So I've been studying the documentation of.net Core Middleware and it mentions there are three types of request delegates: Run, Use and Map. I use app.MapGet() to handle a few specific routes and I have a few app.Use() to filter some incoming requests for various purposes. And I have an app.Run() in my code also. And I wonder why it is actually needed.
If I remove it, the site won't work with a "HTTP Error 500.30 - ASP.NET Core app failed to start" message so I seem to need it.
But then I see this code example:

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

app.Run(async context =>
{
    await context.Response.WriteAsync("Hello world!");
});

app.Run();

And I can't help but wonder why this has an extra app.Run() in it, with parameters. I'm trying to understand why I would use this second app.Run() in my code.
So, what is the use case for having multiple app.Run() commands in my code?

Kirk Larkin
  • 84,915
  • 16
  • 214
  • 203
Wim ten Brink
  • 25,901
  • 20
  • 83
  • 149
  • 1
    "The first Run delegate is always terminal and terminates the pipeline. [...] In the preceding example, the Run delegate writes "Hello from 2nd delegate." to the response and then terminates the pipeline. If another Use or Run delegate is added after the Run delegate, it's not called." - from the page you linked – gunr2171 Dec 29 '22 at 03:47
  • So the problem is why we have two ```app.Run```? – MichaelMao Dec 29 '22 at 06:01

1 Answers1

3

If you check the source code then you will see the second app.Run() is for running the application and listening a URL (check the summary)

    /// <summary>
    /// Runs an application and block the calling thread until host shutdown.
    /// </summary>
    /// <param name="url">The URL to listen to if the server hasn't been configured directly.</param>
    public void Run([StringSyntax(StringSyntaxAttribute.Uri)] string? url = null)
    {
        Listen(url);
        HostingAbstractionsHostExtensions.Run(this);
    }

And the first app.Run(async context => actually it's a wrapper for app.Use. Below is the source code for first one

namespace Microsoft.AspNetCore.Builder;

/// <summary>
/// Extension methods for adding terminal middleware.
/// </summary>
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)
    {
        if (app == null)
        {
            throw new ArgumentNullException(nameof(app));
        }

        if (handler == null)
        {
            throw new ArgumentNullException(nameof(handler));
        }

        app.Use(_ => handler);
    }
}

So let's go back to your question. If we don't have the second app.Run() how to run an application.

MichaelMao
  • 2,596
  • 2
  • 23
  • 54