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

ASP.NET Core Filter Factory示例解析及核心概念疑问求助

ASP.NET Core Endpoint Filter Factory 核心疑问解答

1. EndpointFilterFactoryContext 和 EndpointFilterDelegate 是什么?谁传入工厂函数?

  • EndpointFilterFactoryContext:是过滤器工厂初始化阶段的上下文对象,包含当前端点的静态元数据(比如MethodInfo、端点元数据集合等)。它的作用是让工厂在应用启动时就能获取端点的静态信息,判断是否需要生成对应的过滤逻辑(比如示例中通过MethodInfo获取方法参数)。
  • EndpointFilterDelegate:是代表过滤器链中后续执行环节的委托——可能是下一个过滤器,也可能是端点本身的执行逻辑。它的作用和ASP.NET Core中间件里的next委托类似,调用它就会把请求传递到下一个环节。

这两个参数由ASP.NET Core端点路由框架在应用启动阶段自动传入:当框架扫描并初始化所有端点(Controller Action、Minimal API端点等)时,如果某个端点关联了该Filter Factory,框架会自动构建EndpointFilterFactoryContext实例(填充当前端点的元数据),并把过滤器链中的下一个环节委托(next)传入,调用工厂函数生成最终的请求处理委托。

2. invocationContext 的来源?代码执行逻辑梳理

invocationContext 的来源

示例中的invocationContext是EndpointFilterInvocationContext类型的实例,它是请求执行阶段由框架创建的上下文对象,包含当前请求的所有动态信息:比如请求参数、HttpContext、端点信息等。每次请求到达该端点时,框架都会生成一个新的实例并传入到工厂返回的异步委托中。

完整执行逻辑分两个阶段:

阶段一:应用启动初始化(仅执行一次)

  1. 框架调用ValidateIdFactory,传入当前端点的EndpointFilterFactoryContext和next委托
  2. 工厂通过context.MethodInfo获取端点方法的所有参数,遍历查找名为id且类型为string的参数,记录其位置
  3. 如果找不到符合条件的参数,直接返回原next委托,该过滤器对当前端点不生效
  4. 如果找到参数,返回一个新的异步委托,这个委托就是后续请求到来时要执行的过滤逻辑

阶段二:请求处理(每次请求到达时执行)

  1. 框架创建EndpointFilterInvocationContext实例(即invocationContext),填充当前请求的参数、上下文等信息
  2. 执行工厂返回的异步委托:
    • 通过invocationContext.GetArgument<string>(idPosition.Value)获取请求中的id参数值
    • 验证id:如果为空/空字符串,或者不以s开头,直接返回Results.ValidationProblem结果,终止后续流程
    • 如果验证通过,调用next(invocationContext),将请求传递给下一个过滤器或端点本身,等待执行结果并返回

示例代码

public static EndpointFilterDelegate ValidateIdFactory(
    EndpointFilterFactoryContext context,
    EndpointFilterDelegate next)
{
    ParameterInfo[] parameters = context.MethodInfo.GetParameters();

    int? idPosition = null;

    for (int i = 0; i < parameters.Length; i++)
    {
        if (parameters[i].Name == "id" && parameters[i].ParameterType == typeof(string))
        {
            idPosition = i;
            break;
        }
    }

    if (!idPosition.HasValue)
    {
        return next;
    }

    return async (invocationContext) =>
    {
        string id = invocationContext.GetArgument<string>(idPosition.Value);

        if (string.IsNullOrEmpty(id) || !id.StartsWith('s'))
        {
            return Results.ValidationProblem(new Dictionary<string, string[]>
            {
                { "id", new[] { "Id cannot be null or empty and must start with 's'" } }
            });
        }

        return await next(invocationContext);
    };
}

内容的提问来源于stack exchange,提问作者yinivem462

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:16:12