Resolving the current route/endpoint name in ASP.NET Core 3.1

Endpoint routing was first introduced in ASP.NET Core 2.2 with the goal of making routing a cross-cutting concern, decoupling it from the MVC framework. You can find a detailed write-up on endpoint routing here.

In our applications we use custom middleware to record metrics about our API usage. Rather than recording every single request (including invalid paths), we only record metrics for genuine routes. Our convention is that if you want a controller action to be tracked, you need to give the corresponding route a name:

[HttpPost(Name = "RequestPayment")]
public async Task<IActionResult> PostAsync([FromBody] PaymentRequest request)
{
    ...
}

In ASP.NET Core 2.2 we registered endpoint routing like so:

app.UseEndpointRouting();

To retrieve the current endpoint name (from the MVC route) we used the following extension:

/// <summary>
/// Gets the current API resource name from HTTP context
/// </summary>
/// <param name="httpContext">The HTTP context</param>
/// <returns>The current resource name if available, otherwise an empty string</returns>
public static string GetMetricsCurrentResourceName(this HttpContext httpContext)
{
    if (httpContext == null)
        throw new ArgumentNullException(nameof(httpContext));

    Endpoint endpoint = httpContext.Features.Get<IEndpointFeature>()?.Endpoint;

    return endpoint?.Metadata.GetMetadata<IRouteValuesAddressMetadata>()?.RouteName;
}

As of ASP.NET Core 3.0, the IRouteValuesAddressMetadata type has been removed. To achieve the same result in ASP.NET Core 3.0 onwards, you can do the following:

/// <summary>
/// Gets the current API resource name from HTTP context
/// </summary>
/// <param name="httpContext">The HTTP context</param>
/// <returns>The current resource name if available, otherwise an empty string</returns>
public static string GetMetricsCurrentResourceName(this HttpContext httpContext)
{
    if (httpContext == null)
        throw new ArgumentNullException(nameof(httpContext));

    Endpoint endpoint = httpContext.GetEndpoint();
    return endpoint?.Metadata.GetMetadata<EndpointNameMetadata>()?.EndpointName;
}

Ben Foster

About Me

I'm a software engineer and aspiring entrepreneur with 20 years experience in tech. I've worked with companies of all sizes in areas such as healthcare, agriculture, recruitment, e-commerce, finance and banking. I founded my first startup Fabrik in 2011.

I now head up the engineering team at Checkout.com. If you're interested in working in an exciting and innovative fin-tech company, drop me a message.

Creative Commons Licence