In last article, we have seen that there are two middlewares – UseRouting and UseEndpoints – to enable ASP .NET Core web application. We briefly saw what is responsibility of these two middlewares. Routing is responsible for mapping the incoming URL to find best matching endpoint, which can process the request.
In this article, let’s try to know some basics about endpoint.
In theory, routing is responsible for finding best matching endpoint for incoming URL. Once the endpoint is found, the request is then dispatched to the selected endpoint.
Every endpoint has some information associated with with:
- A request delegate, which is called to process the incoming request
- Metadata collection, to hold some metadata about endpoint. This can be used to make the endpoint extensible.
- Optionally, Routing Information, is also associated with endpoint. This information may include patterns or templates associated with routing.
- collection of endpoints can be listed by retrieving the EndpointDataSource from DI.
UseRouting middleware is responsible for getting this information about Endpoint and set it so that subsequent middleware can use this information.
Once an endpoint is selected, it is always available via HttpContext. Note that endpoint object is immutable, so cannot be modified after it is created.
Let’s try to understand the above theory via an example. We can write some inline middlewares to check which information is made available after UseRouting middleware is executed.
These inline middlewares would print the endpoint information. This would help us understand a bit more about endpoints. We have same inline middleware copied at four different locations:
- Before UseRouting
- After UseRouting
- In Endpoint’s request delegate
- After UseEndpoints
We just are trying to get the endpoint display name if the endpoint information is present.
If we run the application using dotnet CLI, we should see that:
- For any existing URL (Root and Name endpoints), code from step 1, 2 and 3 would execute, but step 1 does not have endpoint information, as it is called before UseRouting.
- For any non-existing URL(any random URL), code from step 1, 2 and 4 would execute. Step 3 is not executed because there was no matching endpoint for incoming URL. Step 4 was executed, because UseEndpoints was not able to provide the response. Hence next middleware (step 4) from pipeline is involved.
From above demo, it can be safely concluded that –
- 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.
I hope you found this information useful. Let me know your thoughts.