【问题标题】:Read Controller and Action name in middleware .Net Core读取中间件 .Net Core 中的 Controller 和 Action 名称
【发布时间】: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
    }       
}

【问题讨论】:

标签: c# asp.net-core middleware


【解决方案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();
         }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-25
      • 2022-12-04
      • 2023-03-10
      • 2019-04-20
      • 1970-01-01
      • 2017-10-06
      • 2020-06-04
      • 2021-06-07
      相关资源
      最近更新 更多