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

在.NET Core 2.2日志中间件中不依赖ControllerContext获取控制器与动作名称的方案咨询

Hey there! I've tackled this exact scenario with .NET Core 2.2 middleware before, so let me break down how to grab controller and action names when ControllerContext isn't accessible. Unlike .NET Core 3.1+, 2.2 doesn't have the Endpoint abstraction, but we can still get this info using MVC's internal features.

Solution 1: Use IActionFeature for reliable, detailed data

This is the most robust approach because it pulls directly from MVC's action descriptor system, which holds all metadata about the matched controller and action.

Here's how to implement it in your middleware:

public class YourCustomMiddleware
{
    private readonly RequestDelegate _next;

    public YourCustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        // First, let the rest of the pipeline run so routing completes
        await _next(context);

        // Fetch the action feature from HttpContext features
        var actionFeature = context.Features.Get<IActionFeature>();
        if (actionFeature != null)
        {
            // Cast to ControllerActionDescriptor to access controller/action details
            var controllerActionDescriptor = actionFeature.ActionDescriptor as ControllerActionDescriptor;
            if (controllerActionDescriptor != null)
            {
                string controllerName = controllerActionDescriptor.ControllerName;
                string actionName = controllerActionDescriptor.ActionName;

                // Pass these values to your logging method
                await LogResponse(controllerName, actionName, context);
            }
        }
    }

    private async Task LogResponse(string controllerName, string actionName, HttpContext context)
    {
        // Example usage: set your ServiceName to controller.action
        ServiceName = $"{controllerName}.{actionName}";
        
        // Add your existing logging logic here
        // ...
    }
}

Critical note about middleware order

Make sure you register your middleware after app.UseMvc() in your Startup.cs Configure method. This ensures the MVC routing system has already processed the request and populated the IActionFeature:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // ... other middleware (like exception handling, static files)

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });

    // Register your middleware HERE, after UseMvc
    app.UseMiddleware<YourCustomMiddleware>();
}

Solution 2: Fallback to RouteData (simpler, less reliable)

If you're using standard MVC routing with {controller} and {action} parameters in your route templates, you can pull the names directly from RouteData. This is quicker but won't work if you have custom routes that don't expose these parameters.

public async Task Invoke(HttpContext context)
{
    await _next(context);

    var routeData = context.GetRouteData();
    if (routeData != null)
    {
        string controllerName = routeData.Values["controller"]?.ToString();
        string actionName = routeData.Values["action"]?.ToString();

        if (!string.IsNullOrEmpty(controllerName) && !string.IsNullOrEmpty(actionName))
        {
            await LogResponse(controllerName, actionName, context);
        }
    }
}

Which one to choose?

  • Use Solution 1 if you need guaranteed access to controller/action names, even with custom routes or attribute routing. It also gives you access to other metadata like action parameters, filters, etc.
  • Use Solution 2 only for simple, standard routing scenarios where you know the controller and action route parameters are always present.

内容的提问来源于stack exchange,提问作者शेखर

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 10:07:32