在中间件.Net Core中读取Controller和Action名称

Met*_*lex 7 c# middleware asp.net-core

我正在我的项目中编写一个中间件类,以便将请求数据记录到我们的数据库中.

我没有看到任何简单的方法来获取控制器名称和操作?有没有机会在核心轻松做到这一点?

我有这样的事情:

public class RequestResponseLoggingMiddleware
{
    private readonly RequestDelegate _next;

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

    public async Task Invoke(HttpContext context)
    {        
        //handle the request
        //something like: context.GetRouteData();

        await _next(context);                 

        //handle the response
    }       
}
Run Code Online (Sandbox Code Playgroud)

小智 28

我遇到了同样的问题,这在 .NetCore 3.1 中对我有用:

public async Task InvokeAsync(HttpContext httpContext)
{
    var controllerActionDescriptor = httpContext
        .GetEndpoint()
        .Metadata
        .GetMetadata<ControllerActionDescriptor>();

    var controllerName = controllerActionDescriptor.ControllerName;
    var actionName = controllerActionDescriptor.ActionName;
            
    await _next(httpContext);
}
Run Code Online (Sandbox Code Playgroud)

为了GetEndpoint()返回 null 的实际端点 instad,必须满足以下条件。

  • 启用端点路由(AddControllers()而不是AddMvc()
  • UseRouting()和之间调用您的中间件UseEndpoints()

  • 如果不是你的最后一个要点,我仍然会用我的头来反对这个!如果您感到烦恼,可能值得以某种方式强调它的重要性,因为恕我直言,这没有得到很好的记录 (4认同)
  • 最后一点对于 .net 6 世界中的我来说并不适用。但谢谢,你的回答有效! (2认同)

Mat*_*rdt 8

在 Ganesh 的回答中,我想添加一些条件。

  • 启用端点路由(AddControllers()而不是AddMvc()
  • UseRouting()在和之间调用您的中间件UseEndpoints()

否则GetEndpoint()返回 null。


Aki*_*oto 6

这可行,但您需要确保_next(context)在查询控制器和操作名称之前调用。

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

    var controllerName = context.GetRouteData().Values["controller"];
    var actionName = context.GetRouteData().Values["action"];
}
Run Code Online (Sandbox Code Playgroud)


Met*_*lex 0

控制器和操作数据可通过过滤器获得,因此我以这种方式实现。控制器和操作数据在 ActionExecutingContext 对象中可用。

public class AsyncActionFilter : IAsyncActionFilter
{
     public AsyncActionFilter(IEntityContext entityContext)
     {
         _entityContext = entityContext;
     }

     public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
     {  
          //Handle the request
          await next();
     }
}
Run Code Online (Sandbox Code Playgroud)