Skip to content

Commit

Permalink
Ensure disabling of implicit child validation works correctly for rec…
Browse files Browse the repository at this point in the history
…ord types (#7) (#8)
  • Loading branch information
JeremySkinner authored Sep 8, 2022
1 parent 065e286 commit 6bdf76c
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
<VersionPrefix>11.2.1</VersionPrefix>
<VersionPrefix>11.2.2</VersionPrefix>
<AssemblyName>FluentValidation.AspNetCore</AssemblyName>
<PackageId>FluentValidation.AspNetCore</PackageId>
<Product>FluentValidation.AspNetCore</Product>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ protected bool ShouldSkip(ModelValidationContext mvContext) {
return true;
}
}
else if (modelMetadata.MetadataKind == ModelMetadataKind.Parameter) {
// If we're working with record types then metadata kind will always be parameter.
if (!ReferenceEquals(rootMetadata, modelMetadata)) {
return true;
}
}
}

return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,11 @@ public ActionResult ImplicitChildCollectionDataAnnotations([FromBody] ParentMode
return TestResult();
}

#if !NETCOREAPP3_1
public ActionResult ImplicitChildWithRecord([FromBody] ParentRecord model) {
return TestResult();
}
#endif

public ActionResult CheckUnvalidated([FromBody] ParentModel6 model) {
return Content(ModelState.Count(x => x.Value.ValidationState == ModelValidationState.Unvalidated).ToString());
Expand Down
22 changes: 22 additions & 0 deletions src/FluentValidation.Tests.AspNetCore/ImplicitValidationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ private HttpClient CreateClient(bool implicitValidationEnabled) {
services.AddScoped<IValidator<CollectionTestModel>, CollectionTestModelValidator>();
services.AddScoped<IValidator<TestModel>, TestModelValidator>();
services.AddScoped<IValidator<TestModel5>, TestModel5Validator>();
#if !NETCOREAPP3_1
services.AddScoped<IValidator<ParentRecord>, ParentRecordValidator>();
services.AddScoped<IValidator<ChildRecord>, ChildRecordValidator>();
#endif
});
}

Expand Down Expand Up @@ -192,5 +196,23 @@ public async void Skips_implicit_child_validation() {
var result = await CreateClient(true).GetErrors("SkipsImplicitChildValidator", new FormData());
result.Count.ShouldEqual(0);
}
#if !NETCOREAPP3_1
[Fact]
public async void Does_not_run_child_validator_when_implicit_child_validation_disabled_for_record() {
var json = @"{""Name"": ""Foo"", ""Child"": { ""Count"": 0 } }";
var client = CreateClient(false);
var result = await client.GetErrorsViaJSONRaw("ImplicitChildWithRecord", json);
result.Count.ShouldEqual(0);
}

[Fact]
public async void Runs_child_validator_when_implicit_child_validation_enabled_for_record() {
var json = @"{""Name"": ""Foo"", ""Child"": { ""Count"": 0 } }";

var client = CreateClient(true);
var result = await client.GetErrorsViaJSONRaw("ImplicitChildWithRecord", json);
result.Count.ShouldEqual(1);
result[0].Name.ShouldEqual("Child.Count");
}
#endif
}
18 changes: 18 additions & 0 deletions src/FluentValidation.Tests.AspNetCore/TestModels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,21 @@ public BadAsyncValidator() {
});
}
}

#if !NETCOREAPP3_1
public sealed record ParentRecord(string Name, ChildRecord Child);

public record ChildRecord(int Count);

public class ParentRecordValidator : AbstractValidator<ParentRecord> {
public ParentRecordValidator() {
RuleFor(x => x.Name).NotNull();
}
}

public class ChildRecordValidator : AbstractValidator<ChildRecord> {
public ChildRecordValidator() {
RuleFor(x => x.Count).GreaterThan(0);
}
}
#endif

0 comments on commit 6bdf76c

Please sign in to comment.