I would like to test the routing of a minimal API WebApplication
. How can I get the route name, given a HttpRequestMessage
?
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRouting().Configure<RouteOptions>(options => {});
var app = builder.Build();
app.MapGet("/hello", () => "Hello!").WithName(RouteNames.Hello);
app.MapGet("/world", () => "World!").WithName(RouteNames.World);
//app.Run();
var request = new HttpRequestMessage(HttpMethod.Get, "/world");
var routeName = GetRouteName(app, request);
Console.WriteLine($"routeName: {routeName}");
string? GetRouteName(WebApplication app, HttpRequestMessage request)
{
return null; // TODO: Implement
}
static class RouteNames
{
public const string Hello = "Hello";
public const string World = "World";
}
Put in a feature request at https://github.com/dotnet/aspnetcore/issues/48034 .
I accepted Chris's answer. It got me on the right track. I'd like to be able to get the endpoint name without executing the actual endpoint, but I'll save that for another day. May be I just don't call next
. Using his answer, we can stuff the endpoint into the response. A test harness can be created to test all of our named endpoints. Here is working code that uses <PackageReference Include="Microsoft.AspNetCore.TestHost" Version="7.0.5" />
:
using Microsoft.AspNetCore.TestHost;
using System.Diagnostics;
var host = new HostBuilder()
.ConfigureWebHost(webHost => webHost.UseTestServer().Configure(app =>
{
app.UseRouting();
app.Use((context, next) =>
{
if (context.GetEndpoint() is Endpoint endpoint)
{
var endpointName = endpoint.Metadata.GetMetadata<IEndpointNameMetadata>()?.EndpointName;
if (endpointName != null)
{
context.Response.Headers.Add(TagKeys.EndpointName, endpointName);
}
}
return next();
});
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/hello", () => "Hello!").WithName(RouteNames.Hello);
endpoints.MapGet("/world", () => "World!").WithName(RouteNames.World);
});
})
.ConfigureServices(services =>
{
services.AddRouting().Configure<RouteOptions>(routeOptions => { });
}
)
).Build();
host.Start();
var httpClient = host.GetTestClient();
await PrintEndpointName(httpClient, new HttpRequestMessage(HttpMethod.Get, "/"));
await PrintEndpointName(httpClient, new HttpRequestMessage(HttpMethod.Get, "/hello"));
await PrintEndpointName(httpClient, new HttpRequestMessage(HttpMethod.Get, "/world"));
async Task PrintEndpointName(HttpClient httpClient, HttpRequestMessage request)
{
var httpResponse = await httpClient.SendAsync(request);
IEnumerable<string>? headers;
httpResponse.Headers.TryGetValues(TagKeys.EndpointName, out headers);
var endpointName = headers?.FirstOrDefault();
Debug.WriteLine($"{((int)httpResponse.StatusCode)} {endpointName}");
}
static class RouteNames
{
public const string Hello = "Hello";
public const string World = "World";
}
static class TagKeys
{
public const string EndpointName = "endpoint.name";
}