I'm building GraphQL API in Asp.Net Core 2.2 using GraphQL.Net 2.4.0
I've created Controller to handle GraphQL Queries:
[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);
}
}
The problem arises when i want to validate some of the Fields in my InputObjectGraphType
, I've implemented IValidationRule
interface.
Prior this im adding Metadata to the field i want to validate so i can easily find it. I;m getting the fieldType but cant fetch the Value to Validate it.
This is the Implementation of the IValidationRule
i Use:
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
));
}
}
}
}
}
});
});
}
}
But here the context.Inputs property is always null.
In the controller this line var inputs = query.Variables.ToInputs();
also produces null. Is this query Variable field and Document Executer's Input Field anything to do with this ?