Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the differences between app.UseRouting() and app.UseEndPoints()?

As I'm trying to understand them, It seem like they are both used to route/map the request to a certain endpoint

like image 907
Ivandro Jao Avatar asked Sep 08 '19 22:09

Ivandro Jao


People also ask

What is app UseRouting ()?

UseRouting adds route matching to the middleware pipeline. This middleware looks at the set of endpoints defined in the app, and selects the best match based on the request. UseEndpoints adds endpoint execution to the middleware pipeline. It runs the delegate associated with the selected endpoint.

What is the difference between app use VS app run while adding middleware?

For app. Run , it adds a terminal middleware delegate to the application's request pipeline. For app. Use , it adds a middleware delegate to the application's request pipeline.

What is IApplicationBuilder in .NET Core?

UseExceptionHandler(IApplicationBuilder) Adds a middleware to the pipeline that will catch exceptions, log them, and re-execute the request in an alternate pipeline. The request will not be re-executed if the response has already started.

What is routing and how can you define routes in ASP.NET Core?

In ASP.NET Core MVC, this process is known as routing. Routing is the process of directing an HTTP request to a controller. Let us now understand how to route requests to different controllers. The ASP.NET Core middleware needs a way to determine if a given HTTP request should go to a controller for processing or not.


3 Answers

UseRouting: Matches request to an endpoint.

UseEndpoints: Execute the matched endpoint.

It decouples the route matching and resolution functionality from the endpoint executing functionality, which until now was all bundled in with the MVC middleware.

This makes the ASP.NET Core framework more flexible and allows other middlewares to act between UseRouting and UseEndpoints. That allows those middlewares to utilize the information from endpoint routing, for example, the call to UseAuthentication must go after UseRouting, so that route information is available for authentication decisions and before UseEndpoints so that users are authenticated before accessing the endpoints.

Update .NET 6

In ASP.NET Core 6, there's no need to have explicit calls to UseRouting or UseEndpoints to register routes. UseRouting can still be used to specify where route matching happens, but UseRouting doesn't need to be explicitly called if routes should be matched at the beginning of the middleware pipeline.

Depending on where app.Use is called in the pipeline, there may not be an endpoint:

app.Use(async (context, next) =>
{
    
    Console.WriteLine("Before routing runs, endpoint is always null here");
    Console.WriteLine($"Endpoint: {context.GetEndpoint()?.DisplayName ?? "null"}");
    await next(context);
});

app.UseRouting();

app.Use(async (context, next) =>
{
    Console.WriteLine("After routing runs, endpoint will be non-null if routing found a match.");
    Console.WriteLine($"Endpoint: {context.GetEndpoint()?.DisplayName ?? "null"}");
    await next(context);
});

app.MapGet("/", (HttpContext context) =>
{
    Console.WriteLine("Runs when this endpoint matches");
    Console.WriteLine($"Endpoint: {context.GetEndpoint()?.DisplayName ?? "null"}");
    return "Hello World!";
}).WithDisplayName("/");

app.UseEndpoints(_ => { });

app.Use(async (context, next) =>
{
    Console.WriteLine("Runs after UseEndpoints - will only run if there was no match.");
    Console.WriteLine($"Endpoint: {context.GetEndpoint()?.DisplayName ?? "null"}");
    await next(context);
});
like image 55
Ali Bayat Avatar answered Oct 23 '22 04:10

Ali Bayat


Based dotnet core documentation:

╔══════════════════════════════════════════╦═══════════════════════════════════════╗
║             app.UseRouting()             ║          app.UseEndPoints()           ║
╠══════════════════════════════════════════╬═══════════════════════════════════════╣
║               Find Endpoint              ║           Execute Endpoint            ║
║                                          ║                                       ║
║  Adds route matching to the middleware   ║  Adds endpoint execution to the       ║
║  pipeline. This middleware looks at the  ║  middleware pipeline.                 ║
║  set of endpoints defined in the app,    ║  It runs the delegate associated      ║
║  and selects the best match based        ║  with the selected endpoint.          ║
║  on the request.                         ║                                       ║
║                                          ║                                       ║
╚══════════════════════════════════════════╩═══════════════════════════════════════╝

Based above table we should take care about some tips:

  1. If the app calls UseStaticFiles, place UseStaticFiles before UseRouting.

  2. it's important that you place the Authentication and Authorization middleware between UseRouting and UseEndPoints .

  3. Any middleware that appears after the UseRouting() call will know which endpoint will run eventually.

  4. Any middleware that appears before the UseRouting() call won't know which endpoint will run eventually.

like image 52
Hamed Naeemaei Avatar answered Oct 23 '22 02:10

Hamed Naeemaei


First of all,you could have a look at their source code:

1.UseRouting

public static IApplicationBuilder UseRouting(this IApplicationBuilder builder)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

        VerifyRoutingServicesAreRegistered(builder);

        var endpointRouteBuilder = new DefaultEndpointRouteBuilder(builder);
        builder.Properties[EndpointRouteBuilder] = endpointRouteBuilder;

        return builder.UseMiddleware<EndpointRoutingMiddleware>(endpointRouteBuilder);
    }

2.UseEndPoint

public static IApplicationBuilder UseEndpoints(this IApplicationBuilder builder, Action<IEndpointRouteBuilder> configure)
    {
        if (builder == null)
        {
            throw new ArgumentNullException(nameof(builder));
        }

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

        VerifyRoutingServicesAreRegistered(builder);

        VerifyEndpointRoutingMiddlewareIsRegistered(builder, out var endpointRouteBuilder);

        configure(endpointRouteBuilder);

        // Yes, this mutates an IOptions. We're registering data sources in a global collection which
        // can be used for discovery of endpoints or URL generation.
        //
        // Each middleware gets its own collection of data sources, and all of those data sources also
        // get added to a global collection.
        var routeOptions = builder.ApplicationServices.GetRequiredService<IOptions<RouteOptions>>();
        foreach (var dataSource in endpointRouteBuilder.DataSources)
        {
            routeOptions.Value.EndpointDataSources.Add(dataSource);
        }

        return builder.UseMiddleware<EndpointMiddleware>();
    }

Then refer to No overload for method 'UseRouting' takes 1 arguments which explains the differences between them in detail.

ASP.NET Core 3 uses a refined endpoint routing which will generally give more control about routing within the application. Endpoint routing works in two separate steps:

In a first step, the requested route is matched agains the configured routes to figure out what route is being accessed.

In a final step, the determined route is being evaluated and the respective middleware, e.g. MVC, is called.

The two steps are set up by app.UseRouting() and app.UseEndpoints(). The former will register the middleware that runs the logic to determine the route. The latter will then execute that route.

Also, refer to

https://asp.net-hacker.rocks/2019/08/12/aspnetcore30-look-into-startup.html https://aregcode.com/blog/2019/dotnetcore-understanding-aspnet-endpoint-routing/

like image 23
Ryan Avatar answered Oct 23 '22 03:10

Ryan