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

Posted

技术标签:

【中文标题】读取中间件 .Net Core 中的 Controller 和 Action 名称【英文标题】:Read Controller and Action name in middleware .Net Core 【发布时间】:2018-02-05 20:00:45 【问题描述】:

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

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

我有这样的事情:

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
           

【问题讨论】:

Route controller and action in middleware的可能重复 How to get the current ASP.NET core controller method name inside the controller using Reflection or another accurate method 我知道但可能太老了? 以上都不适用于 .Net Core 1.1.2! 【参考方案1】:

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

public async Task InvokeAsync(HttpContext context)

    await _next(context);

    var controllerName = context.GetRouteData().Values["controller"];
    var actionName = context.GetRouteData().Values["action"];

【讨论】:

【参考方案2】:

我遇到了同样的问题,这在 .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);

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

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

【讨论】:

如果不是你的最后一个要点,我仍然会为此而努力!如果您感到困扰,可能值得以某种方式强调它的重要性,因为这没有很好的记录恕我直言 我同意本的观点。第二个要点是救生员! 最后一点不适用于 .net 6 世界中的我。不过谢谢,你的回答奏效了!【参考方案3】:

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

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

否则GetEndpoint() 返回null。

【讨论】:

我给了你一个赞成票,但你能否编辑 Ganesh 的答案以包含这个重要的细节。我也不明白他们为什么用 try/catch 把它复杂化。【参考方案4】:

在 .NET Core 2.0 中,您可以在 Filter 中执行此操作:

public class AuthorizationFilter : IAsyncAuthorizationFilter
    
        public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
        
            var controllerActionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
            string controllerName = controllerActionDescriptor?.ControllerName;
            string actionName = controllerActionDescriptor?.ActionName;
        
    

【讨论】:

这不是问题的答案,而是不同问题的答案。这里没有中间件【参考方案5】:

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

public class AsyncActionFilter : IAsyncActionFilter

     public AsyncActionFilter(IEntityContext entityContext)
     
         _entityContext = entityContext;
     

     public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
       
          //Handle the request
          await next();
     

【讨论】:

以上是关于读取中间件 .Net Core 中的 Controller 和 Action 名称的主要内容,如果未能解决你的问题,请参考以下文章

[Asp.Net Core] 命令行参数读取+配置多种读取

如何在启动类中读取应用程序 URL,特别是在 .net core 3.1 中的“ConfigureService”方法中?

如何在 asp net core 2.2 中间件中多次读取请求正文?

在 ASP.Net Core MVC 中读取 JSON 发布数据

带有 SignalR 集线器的 ASP.NET Core 中的范围服务

中间件是什么?在.NET Core中的工作原理又是怎样的呢?10