I simply want to fetch controller name in a middleware. There are a bunch of answers which use RequestContext
or RouteData
like below:
string controllerName = context.Request.RouteValues["controller"].ToString();
I've tried this but it always returns null for me, what is the way to do this in .NET 6?
Update: .NET Version is 6.0.100-rc.1.21458.32
My Program.cs:
var builder = WebApplication.CreateBuilder(args);
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new() { Title = "RMS.Admin.Api", Version = "v1" });
});
builder.Services.AddCoreServices(configuration);
var app = builder.Build();
if (builder.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "RMS.Admin.Api v1"));
}
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseElmah();
app.MapControllers();
app.UseAuditLogMiddleware();
app.UseErrorLoggingMiddleware();
app.Run();
Middleware's invoke method:
public async Task Invoke(HttpContext httpContext, IUserContext userContext, IAuditLogContract auditLogContract)
{
System.Console.WriteLine(httpContext.GetEndpoint()?.Metadata.GetMetadata<ControllerActionDescriptor>());
auditLogContract.Add(new AuditLog
{
LoginStatus = (userContext.Id == "") ? false : true,
Controller = httpContext.Request.RouteValues["controller"]?.ToString(),
// More code here
});
await this.next(httpContext);
}
CodePudding user response:
I've just tested this and it definitely works under .Net 6. Be aware that middleware is order dependant and if your middleware is called before app.UseRouting()
, your RouteValues will be null.
Application code:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
var app = builder.Build();
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
//if you need your route values this is the earliest point you can inject your middleware into the pipeline.
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Use(async (context, next) =>
{
var controller = context.Request.RouteValues["controller"]?.ToString();
await next();
});
app.Run();
tested on
➜ dotnet --version
6.0.100-preview.7.21379.14
CodePudding user response:
Besides the answer from Marco the following solution works too. This is if you need more information on the type of the controller, not just the name, e.g. the TypeInfo
of the controller class, the MethodInfo
of the called action, ....
app.Use(async (e, next) =>
{
var controllerActionDescriptor = e.GetEndpoint()?.Metadata.GetMetadata<ControllerActionDescriptor>();
await next();
});
NOTE It is important that this code is placed after app.UseRouting
otherwise GetEndpoint()
returns null
;