【问题标题】:How to get ASP.NET Core MVC Filters from HttpContext如何从 HttpContext 获取 ASP.NET Core MVC 过滤器
【发布时间】:2018-02-14 00:15:53
【问题描述】:

我正在尝试编写一些中间件,并且需要知道当前操作方法(如果有)是否具有特定的过滤器属性,因此我可以根据它的存在来更改行为。

那么当您实现IResourceFilter 时,是否可以像在ResourceExecutingContext 上那样获得IList<IFilterMetadata> 类型的过滤器集合?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc httpcontext asp.net-core-middleware


    【解决方案1】:

    今天真的不可能。

    在 ASP.NET Core 3.0 中可以实现

    app.UseRouting();
    
    
    app.Use(async (context, next) =>
    {
        Endpoint endpoint = context.GetEndpoint();
    
        YourFilterAttribute filter = endpoint.Metadata.GetMetadata<YourFilterAttribute>();
    
        if (filter != null)
        { 
    
        }
    
        await next();
    });
    
    
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
    

    【讨论】:

    • 现在可以在 ASP.NET Core 3.0 中实现吗?特别是,我有一个来自响应重写中间件的RewriteContext
    【解决方案2】:

    注意:并不是真正直接回答您的问题,但可能会根据您的需要有所帮助(而且代码对于 cmets 来说太长了)

    注意 2:不确定它是否适用于 Core,如果不适用,请告诉我,我会删除答案

    您可以知道,在一个过滤器中,是否同时使用了另一个过滤器:

    public class OneFilter : ActionFilterAttribute, IActionFilter
    {
        void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
        {
            // Check if the Attribute "AnotherFilter" is used
            if (filterContext.ActionDescriptor.IsDefined(typeof(AnotherFilter), true) || filterContext.Controller.GetType().IsDefined(typeof(AnotherFilter), true))
            {
                // things to do if the filter is used
    
            }
        }
    }
    
    public class AnotherFilter : ActionFilterAttribute, IActionFilter
    {
       // filter things
    }
    

    与/或

    你可以在Route数据中放一些数据,让Action知道使用了哪些Filters:

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.RouteData.Values.Add("OneFilterUsed", "true");
        base.OnActionExecuting(filterContext);
    }
    

    ...

    public ActionResult Index()
    {
        if(RouteData.Values["OneFilterUsed"] == "true")
        {
    
        }
    
        return View();
    }
    

    【讨论】:

    • IsDefined 在 .Net Core 的 ActionDescriptor 中不存在。
    • 是的,没有IsDefined(),但可以使用以下内容:if (filterContext.Filters.Any(x =&gt; filters.Contains(typeof(AnotherFilter)));) { // 要做的事情... }
    【解决方案3】:

    ASP.NET Core 3.0 使用一个新的路由,每个动作都是一个Endpoint,动作和控制器的所有属性都存在于Metadata

    你可以这样做。

    app.UseRouting();
    
    
    app.Use(async (context, next) =>
    {
        Endpoint endpoint = context.GetEndpoint();
    
        YourFilterAttribute filter = endpoint.Metadata.GetMetadata<YourFilterAttribute>();
    
        if (filter != null)
        { 
    
        }
    
        await next();
    });
    
    
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
    

    【讨论】:

    • 这与上一篇文章中的代码完全相同(您已对其进行编辑以包含该代码),因此现在是重复的答案
    猜你喜欢
    • 2020-05-08
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    相关资源
    最近更新 更多