You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 6中间件通过HttpContext获取Controller名称返回null的解决方法

.NET 6 中间件获取Controller名称解决方案

根因分析

你遇到的RouteValues["controller"]返回null的核心原因是中间件注册顺序错误:
在.NET 6的WebApplication管道模型中,路由匹配逻辑(负责填充RouteValues、解析端点信息)会在隐式注入的UseRouting中间件执行时完成,而你将UseAuditLogMiddleware注册在了MapControllers之后,中间件执行时路由匹配还未完成,自然拿不到控制器信息。

解决方案

第一步:调整中间件注册顺序

修改Program.cs中的中间件注册顺序,将自定义审计日志、错误日志中间件放到MapControllers之前,调整后代码如下:

// 原有其他配置保持不变
app.UseHttpsRedirection();

app.UseAuthorization();

app.UseElmah();

// 把自定义中间件移到MapControllers之前
app.UseAuditLogMiddleware();
app.UseErrorLoggingMiddleware();

app.MapControllers(); // 端点注册放在自定义中间件之后

app.Run();

第二步:使用稳定的取值方式

调整顺序后可以继续用RouteValues取值,也可以直接从端点元数据中获取ControllerActionDescriptor来拿控制器名称,兼容性更强,不会受自定义路由规则影响:

// 需先引用命名空间 Microsoft.AspNetCore.Mvc.Controllers
public async Task Invoke(HttpContext httpContext, IUserContext userContext, IAuditLogContract auditLogContract)
{
    // 方式1:RouteValues取值(顺序调整后可用)
    var controllerName1 = httpContext.Request.RouteValues["controller"]?.ToString();
    
    // 方式2:从端点元数据取值(更稳定)
    var controllerActionDescriptor = httpContext.GetEndpoint()?.Metadata.GetMetadata<ControllerActionDescriptor>();
    var controllerName2 = controllerActionDescriptor?.ControllerName;

    auditLogContract.Add(new AuditLog
    {
        LoginStatus = !string.IsNullOrEmpty(userContext.Id),
        Controller = controllerName2 ?? controllerName1,
        // 其余代码保持不变
    });

    await this.next(httpContext);
}

注:如果请求命中的是静态文件、Swagger等非Controller端点,拿不到Controller名称属于正常情况,空值判断即可正常兼容。

内容的提问来源于stack exchange,提问作者Amol Borkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 18:36:01