GraphQL-dotnet字段验证事先解决

时间:2019-02-19 14:54:24

标签: c# asp.net-core graphql graphql-dotnet

我正在使用GraphQL.Net 2.4.0在Asp.Net Core 2.2中构建GraphQL API

我创建了Controller以处理GraphQL查询:

    [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接口中的某些字段时,就会出现问题。

在此之前,我向要验证的字段添加了元数据,因此我可以轻松找到它。我正在获取fieldType,但无法获取该值来对其进行验证。

这是IValidationRule我使用的实现:

IValidationRule

但是这里的context.Inputs属性始终为null。 在控制器中,此行 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 )); } } } } } }); }); } } 也产生null。此查询变量字段和文档执行者的输入字段与此有关吗?

1 个答案:

答案 0 :(得分:0)

您现在可能已经知道了,但是对于将来发现此问题的任何人: context.Inputs仅与变量一起使用。 据我了解,argAst.GetValue可以是VariableReference或ObjectValue,具体取决于查询是否使用了变量。 如果未使用变量,则context.Inputs.GetValue将返回null。