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

ChilliCream GraphQL中如何在查询参数上使用自定义指令

问题说明

基于.NET Core 6框架搭配ChilliCream v12(Hot Chocolate)开展GraphQL开发时,自定义指令可在类型字段上正常运行,但绑定到查询/变更操作的指定参数上时无法生效。
执行如下查询语句时,仅UserType的Name字段上的指令可正常触发,userByEmail查询的email参数上挂载的指令无响应:

query{
  userByEmail(email: "test") {
    id
    name
    email
  }
}
解决方案

Hot Chocolate v12 默认的指令执行管道仅覆盖字段级维度,参数级指令不会自动被字段中间件捕获,需要做两处调整即可让参数指令正常生效:

  • 显式指定指令的适用范围
    给自定义指令类型配置允许挂载的位置时,除了原本的字段定义位置,必须额外加上DirectiveLocation.ArgumentDefinition,示例配置如下:
    [DirectiveType(
        DirectiveLocation.FieldDefinition | 
        DirectiveLocation.ArgumentDefinition // 新增参数定义的挂载位置
    )]
    public class MyCustomDirective : DirectiveType
    {
        protected override void Configure(IDirectiveTypeDescriptor descriptor)
        {
            descriptor.Name("myCustomDirective");
            // 保留原有的指令参数、配置逻辑即可
        }
    }
    
  • 注册参数级中间件处理指令逻辑
    不要仅依赖字段级UseField中间件处理所有指令逻辑,需要单独实现参数中间件,在服务注册阶段注入管道,用来捕获参数上挂载的指令并执行对应逻辑:
    1. 先实现自定义参数中间件,遍历当前执行字段的所有入参,检测参数上的指令并处理:
      public class CustomArgumentDirectiveMiddleware
      {
          private readonly FieldDelegate _next;
      
          public CustomArgumentDirectiveMiddleware(FieldDelegate next)
          {
              _next = next;
          }
      
          public async ValueTask InvokeAsync(IMiddlewareContext context)
          {
              // 遍历当前字段的所有入参
              foreach (var argument in context.Selection.Field.Arguments)
              {
                  // 检测当前参数是否挂载了自定义指令
                  if (argument.Directives.Contains<MyCustomDirective>())
                  {
                      // 读取参数传入值,执行校验、转换、日志等自定义逻辑
                      var argumentValue = context.ArgumentValue<object>(argument.Name);
                      // 此处写指令对应的业务逻辑即可
                  }
              }
              await _next(context);
          }
      }
      
    2. 在GraphQL服务注册时,把中间件加入管道:
      builder.Services.AddGraphQLServer()
          // 保留原有的查询类型、类型绑定等注册代码
          .AddArgumentMiddleware<CustomArgumentDirectiveMiddleware>();
      

如果是用注解模式给参数绑定指令,直接在查询/变更方法的对应参数上添加指令特性即可,示例:

public User? GetUserByEmail([MyCustomDirective] string email)
{
    // 原有业务查询逻辑
}

配置完成后重新启动项目,参数上的自定义指令就可以和字段指令一样正常触发执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 23:30:38