diff --git a/src/GraphQL.FluentValidation/ArgumentValidation.cs b/src/GraphQL.FluentValidation/ArgumentValidation.cs
index 5db2d07d..8f09a682 100644
--- a/src/GraphQL.FluentValidation/ArgumentValidation.cs
+++ b/src/GraphQL.FluentValidation/ArgumentValidation.cs
@@ -64,4 +64,4 @@ static ValidationContext BuildValidationContext(object? instance, object userCon
validationContext.RootContextData.Add("UserContext", userContext);
return validationContext;
}
-}
\ No newline at end of file
+}
diff --git a/src/GraphQL.FluentValidation/FluentValidationExtensions.cs b/src/GraphQL.FluentValidation/FluentValidationExtensions.cs
index e3b8b1ea..88826ef6 100644
--- a/src/GraphQL.FluentValidation/FluentValidationExtensions.cs
+++ b/src/GraphQL.FluentValidation/FluentValidationExtensions.cs
@@ -1,6 +1,5 @@
using FluentValidation;
using GraphQL.FluentValidation;
-using GraphQL.Types;
namespace GraphQL
{
@@ -9,17 +8,6 @@ namespace GraphQL
///
public static partial class FluentValidationExtensions
{
- ///
- /// Validate an instance against the current cached validators defined by .
- ///
- public static void ValidateInstance(this ResolveFieldContext context, TInstance input)
- {
- Guard.AgainstNull(context, nameof(context));
- Guard.AgainstNull(input, nameof(input));
- var type = input!.GetType();
- ArgumentValidation.Validate(ArgumentTypeCacheBag.GetCache(context), type, input, context.UserContext);
- }
-
///
/// Adds a FieldMiddleware to the GraphQL pipeline that converts a to s./>
///
diff --git a/src/Tests/Arguments/AsyncComplexInput.cs b/src/Tests/Arguments/AsyncComplexInput.cs
new file mode 100644
index 00000000..6ed24650
--- /dev/null
+++ b/src/Tests/Arguments/AsyncComplexInput.cs
@@ -0,0 +1,4 @@
+public class AsyncComplexInput
+{
+ public ComplexInputInner? Inner { get; set; }
+}
\ No newline at end of file
diff --git a/src/Tests/Arguments/AsyncComplexInputGraph.cs b/src/Tests/Arguments/AsyncComplexInputGraph.cs
new file mode 100644
index 00000000..be36a5ba
--- /dev/null
+++ b/src/Tests/Arguments/AsyncComplexInputGraph.cs
@@ -0,0 +1,10 @@
+using GraphQL.Types;
+
+public class AsyncComplexInputGraph :
+ InputObjectGraphType
+{
+ public AsyncComplexInputGraph()
+ {
+ Field("inner");
+ }
+}
\ No newline at end of file
diff --git a/src/Tests/Arguments/AsyncComplexInputValidator.cs b/src/Tests/Arguments/AsyncComplexInputValidator.cs
new file mode 100644
index 00000000..0c10b6ec
--- /dev/null
+++ b/src/Tests/Arguments/AsyncComplexInputValidator.cs
@@ -0,0 +1,16 @@
+using FluentValidation;
+using System.Threading.Tasks;
+
+public class AsyncComplexInputValidator :
+ AbstractValidator
+{
+ public AsyncComplexInputValidator()
+ {
+ RuleFor(_ => _.Inner!)
+ .NotEmpty()
+ .MustAsync((o, token) => {
+ return Task.FromResult(o != null && !string.IsNullOrWhiteSpace(o.Content));
+ }).WithMessage("Inner async test failed msg.")
+ .SetValidator(new ComplexInputInnerValidator());
+ }
+}
\ No newline at end of file
diff --git a/src/Tests/Arguments/ComplexInput.cs b/src/Tests/Arguments/ComplexInput.cs
index 27c01f11..2f0a5423 100644
--- a/src/Tests/Arguments/ComplexInput.cs
+++ b/src/Tests/Arguments/ComplexInput.cs
@@ -1,4 +1,8 @@
-public class ComplexInput
+using System.Collections.Generic;
+
+public class ComplexInput
{
public ComplexInputInner? Inner { get; set; }
+
+ public List? Items { get; set; }
}
\ No newline at end of file
diff --git a/src/Tests/Arguments/ComplexInputGraph.cs b/src/Tests/Arguments/ComplexInputGraph.cs
index 2c6e706e..68ea92fd 100644
--- a/src/Tests/Arguments/ComplexInputGraph.cs
+++ b/src/Tests/Arguments/ComplexInputGraph.cs
@@ -6,5 +6,7 @@ public class ComplexInputGraph :
public ComplexInputGraph()
{
Field("inner");
+
+ Field>>("items");
}
}
\ No newline at end of file
diff --git a/src/Tests/Arguments/ComplexInputListItem.cs b/src/Tests/Arguments/ComplexInputListItem.cs
new file mode 100644
index 00000000..376739a7
--- /dev/null
+++ b/src/Tests/Arguments/ComplexInputListItem.cs
@@ -0,0 +1,5 @@
+public class ComplexInputListItem
+{
+ public int Id { get; set; }
+ public string? Content { get; set; }
+}
\ No newline at end of file
diff --git a/src/Tests/Arguments/ComplexInputListItemGraph.cs b/src/Tests/Arguments/ComplexInputListItemGraph.cs
new file mode 100644
index 00000000..878d5148
--- /dev/null
+++ b/src/Tests/Arguments/ComplexInputListItemGraph.cs
@@ -0,0 +1,16 @@
+using GraphQL.Types;
+
+public class ComplexInputListItemGraph :
+ InputObjectGraphType
+{
+ public ComplexInputListItemGraph()
+ {
+ Field>()
+ .Name("id")
+ .Resolve(ctx => ctx.Source.Id);
+
+ Field()
+ .Name("content")
+ .Resolve(ctx => ctx.Source.Content);
+ }
+}
\ No newline at end of file
diff --git a/src/Tests/Arguments/ComplexInputListItemValidator.cs b/src/Tests/Arguments/ComplexInputListItemValidator.cs
new file mode 100644
index 00000000..08056e83
--- /dev/null
+++ b/src/Tests/Arguments/ComplexInputListItemValidator.cs
@@ -0,0 +1,14 @@
+using FluentValidation;
+
+public class ComplexInputListItemValidator :
+ AbstractValidator
+{
+ public ComplexInputListItemValidator()
+ {
+ RuleFor(_ => _.Id)
+ .NotEmpty();
+
+ RuleFor(_ => _.Content)
+ .NotEmpty();
+ }
+}
\ No newline at end of file
diff --git a/src/Tests/Arguments/ComplexInputValidator.cs b/src/Tests/Arguments/ComplexInputValidator.cs
index 52831278..ef74fbf0 100644
--- a/src/Tests/Arguments/ComplexInputValidator.cs
+++ b/src/Tests/Arguments/ComplexInputValidator.cs
@@ -8,5 +8,9 @@ public ComplexInputValidator()
RuleFor(_ => _.Inner!)
.NotEmpty()
.SetValidator(new ComplexInputInnerValidator());
+
+ RuleFor(_ => _.Items)
+ .NotEmpty()
+ .ForEach(i => i.SetValidator(new ComplexInputListItemValidator()));
}
}
\ No newline at end of file
diff --git a/src/Tests/IntegrationTests.AsyncComplexInvalid.approved.txt b/src/Tests/IntegrationTests.AsyncComplexInvalid.approved.txt
new file mode 100644
index 00000000..17aa2d14
--- /dev/null
+++ b/src/Tests/IntegrationTests.AsyncComplexInvalid.approved.txt
@@ -0,0 +1,13 @@
+{
+ data: {
+ asyncComplexInputQuery: null
+ },
+ errors: [
+ {
+ message: 'Inner: Inner async test failed msg.'
+ },
+ {
+ message: 'Inner.Content: \'Content\' must not be empty.'
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/Tests/IntegrationTests.AsyncComplexValid.approved.txt b/src/Tests/IntegrationTests.AsyncComplexValid.approved.txt
new file mode 100644
index 00000000..5b85e1c9
--- /dev/null
+++ b/src/Tests/IntegrationTests.AsyncComplexValid.approved.txt
@@ -0,0 +1,7 @@
+{
+ data: {
+ asyncComplexInputQuery: {
+ data: 'TheContent'
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Tests/IntegrationTests.ComplexInvalid.approved.txt b/src/Tests/IntegrationTests.ComplexInvalid.approved.txt
index 7827fe82..a629e50e 100644
--- a/src/Tests/IntegrationTests.ComplexInvalid.approved.txt
+++ b/src/Tests/IntegrationTests.ComplexInvalid.approved.txt
@@ -5,6 +5,9 @@
errors: [
{
message: 'Inner.Content: \'Content\' must not be empty.'
+ },
+ {
+ message: 'Items: \'Items\' must not be empty.'
}
]
}
\ No newline at end of file
diff --git a/src/Tests/IntegrationTests.ComplexInvalid2.approved.txt b/src/Tests/IntegrationTests.ComplexInvalid2.approved.txt
index 894a6e86..450ea24c 100644
--- a/src/Tests/IntegrationTests.ComplexInvalid2.approved.txt
+++ b/src/Tests/IntegrationTests.ComplexInvalid2.approved.txt
@@ -5,6 +5,9 @@
errors: [
{
message: 'Inner: \'Inner\' must not be empty.'
+ },
+ {
+ message: 'Items: \'Items\' must not be empty.'
}
]
}
\ No newline at end of file
diff --git a/src/Tests/IntegrationTests.ComplexValid.approved.txt b/src/Tests/IntegrationTests.ComplexValid.approved.txt
index c1d5c696..b087116b 100644
--- a/src/Tests/IntegrationTests.ComplexValid.approved.txt
+++ b/src/Tests/IntegrationTests.ComplexValid.approved.txt
@@ -1,7 +1,7 @@
{
data: {
complexInputQuery: {
- data: 'TheContent'
+ data: '{"Inner":{"Content":"TheContent"},"Items":[{"Id":1,"Content":"Some content 1"},{"Id":2,"Content":"Some content 2"}]}'
}
}
}
\ No newline at end of file
diff --git a/src/Tests/IntegrationTests.cs b/src/Tests/IntegrationTests.cs
index 6fa50da1..c23bf11c 100644
--- a/src/Tests/IntegrationTests.cs
+++ b/src/Tests/IntegrationTests.cs
@@ -100,7 +100,11 @@ public async Task ComplexValid()
input: {
inner: {
content: ""TheContent""
- }
+ },
+ items: [
+ { id: 1, content: ""Some content 1"" },
+ { id: 2, content: ""Some content 2"" }
+ ]
}
)
{
@@ -121,7 +125,8 @@ public async Task ComplexInvalid()
input: {
inner: {
content: """"
- }
+ },
+ items: []
}
)
{
@@ -140,7 +145,8 @@ public async Task ComplexInvalid2()
complexInputQuery
(
input: {
- inner: null
+ inner: null,
+ items: null
}
)
{
@@ -151,6 +157,54 @@ public async Task ComplexInvalid2()
ObjectApprover.Verify(result);
}
+ [Fact]
+ public async Task AsyncComplexValid()
+ {
+ var queryString = @"
+{
+ asyncComplexInputQuery
+ (
+ input: {
+ inner: {
+ content: ""TheContent""
+ },
+ items: [
+ { id: 1, content: ""Some content 1"" },
+ { id: 2, content: ""Some content 2"" }
+ ]
+ }
+ )
+ {
+ data
+ }
+}";
+ var result = await QueryExecutor.ExecuteQuery(queryString, null, typeCache);
+ ObjectApprover.Verify(result);
+ }
+
+ [Fact]
+ public async Task AsyncComplexInvalid()
+ {
+ var queryString = @"
+{
+ asyncComplexInputQuery
+ (
+ input: {
+ inner: {
+ content: """"
+ },
+ items: null
+ }
+ )
+ {
+ data
+ }
+}";
+ var result = await QueryExecutor.ExecuteQuery(queryString, null, typeCache);
+ ObjectApprover.Verify(result);
+ }
+
+
public IntegrationTests(ITestOutputHelper output) :
base(output)
{
diff --git a/src/Tests/Query.cs b/src/Tests/Query.cs
index 7f677e36..37ec0aa2 100644
--- a/src/Tests/Query.cs
+++ b/src/Tests/Query.cs
@@ -1,5 +1,6 @@
-using GraphQL;
+using GraphQL;
using GraphQL.Types;
+using Newtonsoft.Json;
public class Query :
ObjectGraphType
@@ -31,7 +32,7 @@ public Query()
var input = context.GetValidatedArgument("input");
return new Result
{
- Data = input.Inner!.Content
+ Data = JsonConvert.SerializeObject(input)
};
}
);
@@ -50,6 +51,21 @@ public Query()
};
}
);
+
+ FieldAsync(
+ "asyncComplexInputQuery",
+ arguments: new QueryArguments(
+ new QueryArgument { Name = "input", }
+ ),
+ resolve: async context =>
+ {
+ var input = await context.GetValidatedArgumentAsync("input");
+ return new Result
+ {
+ Data = input.Inner!.Content
+ };
+ }
+ );
}
}
\ No newline at end of file