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

8

113

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

Anthropomorphosis answered 8/9, 2019 at 22:13 Comment(1)
Its in the docs. Reference Routing in ASP.NET CoreIntemperate
P
96

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);
});
Publia answered 29/1, 2020 at 11:32 Comment(0)
T
66

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.

Toxin answered 24/4, 2020 at 16:42 Comment(4)
Any particular reason why to place the Authentication and Authorization middleware between UseRouting and UseEndPoints?Fenrir
@AlexKlaus Please read this answerToxin
It mentions UseAuthorization only that does have a documented requirement to appear between UseRouting and UseEndpoints. UseAuthentication is a different story (and your link places it much earlier).Fenrir
I think authentication middleware does not require route information this and this if the authentication is done before routing, there is no problem, probably On the other hand if this change is made, all requests will be authenticated, regardless of whether the route is correct or notToxin
S
25

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/

Selfrealization answered 9/9, 2019 at 1:37 Comment(1)
what a terrible design, that we have to go inside the code of a framework to work out what it all means.Pluperfect
E
13

The middleware added by UseRouting() calculates what route should be used for a request URL path, but doesn't route at this point in the pipeline. It adds metadata that can be used by subsequent middleware.

The middleware added by UseEndpoints() executes the Controller and corresponding handler.

UseEndpoints() is also where you actually register all the endpoints for your application

Take a look at this helpful write-up: https://andrewlock.net/converting-a-terminal-middleware-to-endpoint-routing-in-aspnetcore-3/

Expugnable answered 12/1, 2020 at 4:45 Comment(1)
This is the only explanation I've found, after a long search, that succinctly and accurately explains the difference. All others are vague in the extreme. However I think it's important to distinguish between the extension methods and the middleware itself. I'm going to edit the answer to add that distinction.Helwig
W
7

Great answers here already but let me add my answer with an example that's a bit more explained. This is all from the excellent docs.

Definitions:

  1. 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.

    Put simply: Urls are matched to the endpoints.

  2. UseEndpoints adds endpoint execution to the middleware pipeline. It runs the delegate associated with the selected endpoint.

    Put simply: Actual endpoints are registered.

Example:

// Location 1: before routing runs, endpoint is always null here.
// This will run for any endpoint. "/" or "/abc" or "/def" or whatever.
// It won't have any endpoint because it's placed before app.UseRouting()
app.Use(async (context, next) =>
{
    Console.WriteLine($"1. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

app.UseRouting();

// Location 2: after routing runs, endpoint will be non-null if routing found a match.
// This will run for any endpoint. "/" or "/abc" or "/def" or whatever.
// It will have an endpoint only for "/" because there's a match for "/" below (app.MapGet("/"...)
app.Use(async (context, next) =>
{
    Console.WriteLine($"2. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

// Location 3: runs when this endpoint matches
// This will run only for "/"
// Will have an endpoint (Of course! Duh!)
app.MapGet("/", (HttpContext context) =>
{
    Console.WriteLine($"3. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return "Hello World!";
}).WithDisplayName("Hello");

//UseEndpoints middleware is terminal when a match is found
//The middleware after UseEndpoints execute only when no match is found
app.UseEndpoints(_ => { });

// Location 4: runs after UseEndpoints - will only run if there was no match.
// This will run for any endpoint except "/". For eg: "/abc" or "/def" or whatever.
app.Use(async (context, next) =>
{
    Console.WriteLine($"4. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

Running this code with a URL of "/" displays:

1. Endpoint: (null)
2. Endpoint: Hello
3. Endpoint: Hello

Running this code with any other URL displays:

1. Endpoint: (null)
2. Endpoint: (null)
4. Endpoint: (null)
Whim answered 28/9, 2023 at 20:20 Comment(0)
P
1
  • Any modification to the incoming request and data, that routing depends on, can be modified only before UseRouting.
  • UseRouting will use the routing data to select appropriate, best-matching endpoint
  • Any middleware, which comes after UseRouting and before UseEndpoints, can use endpoint information to apply some additional checks before the endpoint is executed. This might include checking CORS configurations, authentication and authorization checks, etc.
  • UseEndpoints is a terminal middleware, provided the endpoint is existing in the application. This means any middleware after it would not be executed if the endpoint was found.
  • Any middleware after UseEndpoints middleware would be executed only for those requests for which endpoints were not configured.

For Better Understanding: https://thecodeblogger.com/2021/05/27/asp-net-core-web-application-routing-and-endpoint-internals/

Paragraph answered 13/10, 2022 at 7:43 Comment(0)
M
0

app.UseRouting()

Marks the position in the middleware pipeline where a routing decision is made or where request is matched to endpoints. In Other words where the endpoint is selected.

app.UseEndPoints()

Marks the position in the middleware pipeline where the selected endpoint is executed. It Execute the endpoints.

Mariettemarigold answered 28/1, 2021 at 12:34 Comment(0)
F
-1

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.

app.UseEndpoints :

UseEndpoints adds endpoint execution to the middleware pipeline. It runs the delegate associated with the selected endpoint.

An endpoint is something that can be:

  1. Selected, by matching the URL and HTTP method.
  2. Executed, by running the delegate.

Endpoints that can be matched and executed by the app are configured in UseEndpoints

Formaldehyde answered 22/12, 2021 at 6:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.