首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GraphQL-dotnet字段验证之前解析

GraphQL-dotnet字段验证之前解析
EN

Stack Overflow用户
提问于 2019-02-19 22:54:24
回答 1查看 1.5K关注 0票数 0

我正在使用GraphQL 2.4.0在Asp.Net核心2.2中构建GraphQL.Net应用程序接口

我已经创建了控制器来处理GraphQL查询:

代码语言:javascript
复制
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class GraphQLController : Controller
{
    private readonly ISchema _schema;
    private readonly IDocumentExecuter _executer;
    private readonly ILogger _logger;
    IEnumerable<IValidationRule> _validationRules;
    private readonly DataLoaderDocumentListener _dataLoaderDocumentListener;

    //private readonly IDocumentWriter _writer;
    //private readonly IHttpContextAccessor _accessor;

    public GraphQLController(
        ILogger<GraphQLController> logger,
        IEnumerable<IValidationRule> validationRules,
        IDocumentExecuter executer,
        DataLoaderDocumentListener dataLoaderDocumentListener,
        //IDocumentWriter writer,
        ISchema schema)
    {
        _executer = executer;
        _schema = schema;
        _logger = logger;
        _validationRules = validationRules;
        _dataLoaderDocumentListener = dataLoaderDocumentListener;
        //_writer = writer;
    }

    [Route("graphql")]
    [HttpPost]
    public async Task<IActionResult> PostAsync([FromBody]GraphQLQuery query)
    {

        if (!ModelState.IsValid || query == null)
        {
            return Json("Проблем в формата на изпратената на заявка!");
        }            

        var inputs = query.Variables.ToInputs();

        var result = await _executer.ExecuteAsync(o =>
        {
            o.Schema = _schema;
            o.Query = query.Query;
            o.OperationName = query.OperationName;
            o.Inputs = inputs;
            o.ExposeExceptions = true;
            o.EnableMetrics = true;

            o.ComplexityConfiguration = new GraphQL.Validation.Complexity.ComplexityConfiguration { MaxDepth = 15 };
            //o.FieldMiddleware.Use<InstrumentFieldsMiddleware>();
            o.UserContext = new GraphQLUserContext
            {
                // this is the User on your controller
                // which is populated from your jwt
                User = User

            };
            o.ValidationRules = DocumentValidator.CoreRules().Concat(_validationRules).ToList();
            o.Listeners.Add(_dataLoaderDocumentListener);

        }).ConfigureAwait(false);

        if (result.Errors?.Count > 0)
        {
            _logger.LogWarning($"Errors: {JsonConvert.SerializeObject(result.Errors)}");
            return BadRequest(result);
        }

        return Ok(result);
    }
}

当我想要验证我的InputObjectGraphType中的一些字段时,问题就出现了,因为我已经实现了IValidationRule接口。

在此之前,我将元数据添加到我想要验证的字段,这样我就可以很容易地找到它。我正在获取fieldType,但无法获取用于验证它的值。

这是我使用的IValidationRule的实现:

代码语言:javascript
复制
    public class PhoneNumberValidationRule : IValidationRule
{
    public INodeVisitor Validate(ValidationContext context)
    {
        return new EnterLeaveListener(_ =>
        {
            _.Match<Argument>(argAst =>
            {
                var inputType = context.TypeInfo.GetInputType().GetNamedType() as InputObjectGraphType;
                var argDef = context.TypeInfo.GetArgument();
                if (argDef == null) return;

                var type = argDef.ResolvedType;
                if (type.IsInputType())
                {
                    var fields = ((type as NonNullGraphType)?.ResolvedType as IComplexGraphType)?.Fields;

                    if (fields != null)
                    {
                        foreach (var field in fields)
                        {
                            if (field.ResolvedType is NonNullGraphType)
                            {
                                if ((field.ResolvedType as NonNullGraphType).ResolvedType is IComplexGraphType)
                                {
                                    fields = fields.Union(((field.ResolvedType as NonNullGraphType).ResolvedType as IComplexGraphType)?.Fields);
                                }
                            }
                            if (field.ResolvedType is IComplexGraphType)
                            {
                                fields = fields.Union((field.ResolvedType as IComplexGraphType)?.Fields);
                            }
                        }

                        //let's look for fields that have a specific metadata
                        foreach (var fieldType in fields.Where(f => f.HasMetadata(nameof(EmailAddressValidationRule))))
                        {
                            //now it's time to get the value
                            context.Inputs.GetValue(argAst.Name, fieldType.Name);
                            if (value != null)
                            {
                                if (!value.IsValidPhoneNumber())
                                {
                                    context.ReportError(new ValidationError(context.OriginalQuery
                                    , "Invalid Phone Number"
                                    , "The supplied phone number is not valid."
                                    , argAst
                                    ));
                                }
                            }
                        }
                    }
                }
            });
        });
    }
}

但在这里,context.Inputs属性始终为空。在控制器中,这一行var inputs = query.Variables.ToInputs();也会生成null。这个查询变量字段和文档执行器的输入字段是否与此有关?

EN

回答 1

Stack Overflow用户

发布于 2019-11-10 17:13:43

现在您可能已经明白了这一点,但是对于将来发现这个问题的任何人来说: context.Inputs只与变量一起使用。据我所知,根据查询是否使用变量,argAst.GetValue可以是VariableReference,也可以是ObjectValue。如果没有使用变量,context.Inputs.GetValue将返回null。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54769052

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档