I have a small sandbox application based on the ASP.NET Core Web API template where I am attempting to modify the controller/action to be used based on a custom header and to facilitate this I am replacing the value of the context.Request.Path
property.
However, despite confirming via debugging that the middleware is running, that the conditions for replacement are being met and that the value of Request.Path
have been changed, the application is still using the controller and action that would have been used should the path have remain unchanged.
The configuration of the application is:
using Sandbox.Middleware;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseMiddleware<ModifyControllerMiddleware>();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
And the middleware itself:
namespace Sandbox.Middleware
{
public class ModifyControllerMiddleware
{
private readonly RequestDelegate _next;
public ModifyControllerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
switch (context.Request.Headers["x-intercept"])
{
case "1":
context.Request.Path = "/Diagnostics/Heartbeat";
break;
case "2":
context.Request.Path = "/Diagnostics/Deadbeat";
break;
}
await _next(context);
}
}
}
What am I doing wrong here?
To summarize my expectations:
https://myapplication.com/Diagnostics/Heartbeat
Heartbeat
action of the Diagnostics
controllerhttps://myapplication.com/Diagnostics/Heartbeat
Deadbeat
action of the Diagnostics
controllerHowever, the actual behaviour is that when calling the above uri it is always the Heartbeat
action that is called regardless of the presence or value of the custom header even though I can see that the value of context.Request.Path
has been changed.
According to your description, you should add app.UseRouting();
before the
app.MapControllers, then modifying the context.path could work.
Like below :
app.UseMiddleware<ModifyControllerMiddleware>();
app.UseErrorHandler();
app.UseAuthorization();
//add this
app.UseRouting();
app.MapControllers();
app.Run();
This is my middelware:
public class ModifyControllerMiddleware
{
private readonly RequestDelegate _next;
public ModifyControllerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
switch (context.Request.Headers["x-intercept"])
{
case "1":
context.Request.Path = "/api/mydata";
break;
case "2":
context.Request.Path = "/GetWeatherForecast";
//context.Request.Path = "/Diagnostics/Deadbeat";
break;
}
await _next(context);
}
}
Result: