diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ea50df9..26a97d1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: build: strategy: matrix: - os: ['windows-2019', 'ubuntu-20.04'] + os: ['windows-latest', 'ubuntu-latest'] runs-on: ${{ matrix.os }} steps: - name: Checkout @@ -24,6 +24,7 @@ jobs: uses: actions/setup-dotnet@v2 with: dotnet-version: | + 9.0.x 7.0.100 6.0.x diff --git a/global.json b/global.json index 77c776f..cdbb589 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.100", + "version": "9.0.100", "rollForward": "latestFeature" } } diff --git a/src/FluentValidation.AspNetCore/FluentValidationModelValidatorProvider.cs b/src/FluentValidation.AspNetCore/FluentValidationModelValidatorProvider.cs index 7cb53dc..95f6dd4 100644 --- a/src/FluentValidation.AspNetCore/FluentValidationModelValidatorProvider.cs +++ b/src/FluentValidation.AspNetCore/FluentValidationModelValidatorProvider.cs @@ -133,9 +133,13 @@ public virtual IEnumerable Validate(ModelValidationContex IValidationContext context = new ValidationContext(mvContext.Model, new PropertyChain(), selector); context.RootContextData["InvokedByMvc"] = true; -#pragma warning disable CS0618 - context.SetServiceProvider(mvContext.ActionContext.HttpContext.RequestServices); -#pragma warning restore CS0618 + + // For backwards compatibility, store the service provider in the validation context. + // This approach works with both FluentValidation.DependencyInjectionExtensions 11.x + // and FluentValidation.DependencyInjectionExtensions 12.x. + // Do not use context.SetServiceProvider extension method as this no longer + // exists in 12.x. + context.RootContextData["_FV_ServiceProvider"] = mvContext.ActionContext.HttpContext.RequestServices; if (interceptor != null) { // Allow the user to provide a customized context diff --git a/src/FluentValidation.Tests.AspNetCore/DependencyInjectionTests.cs b/src/FluentValidation.Tests.AspNetCore/DependencyInjectionTests.cs index 54c6eda..e8e159c 100644 --- a/src/FluentValidation.Tests.AspNetCore/DependencyInjectionTests.cs +++ b/src/FluentValidation.Tests.AspNetCore/DependencyInjectionTests.cs @@ -12,6 +12,7 @@ namespace FluentValidation.Tests; #pragma warning disable CS0618 +#if !NET9_0 public class DependencyInjectionTests : IClassFixture { private readonly ITestOutputHelper _output; private readonly HttpClient _client; @@ -51,3 +52,4 @@ public async Task Resolves_explicit_child_validator_for_collection() { result.GetError("Children[0].Name").ShouldEqual("NotNullInjected"); } } +#endif diff --git a/src/FluentValidation.Tests.AspNetCore/FluentValidation.Tests.AspNetCore.csproj b/src/FluentValidation.Tests.AspNetCore/FluentValidation.Tests.AspNetCore.csproj index 3788895..c107c8a 100644 --- a/src/FluentValidation.Tests.AspNetCore/FluentValidation.Tests.AspNetCore.csproj +++ b/src/FluentValidation.Tests.AspNetCore/FluentValidation.Tests.AspNetCore.csproj @@ -1,6 +1,6 @@  - net6.0;net7.0 + net6.0;net7.0;net9.0 false FluentValidation.Tests true @@ -25,6 +25,13 @@ + + + + + + + diff --git a/src/FluentValidation.Tests.AspNetCore/TestModels.cs b/src/FluentValidation.Tests.AspNetCore/TestModels.cs index d76b6a6..77854e1 100644 --- a/src/FluentValidation.Tests.AspNetCore/TestModels.cs +++ b/src/FluentValidation.Tests.AspNetCore/TestModels.cs @@ -422,6 +422,7 @@ public class ChildModel7 { public string Name { get; set; } } +#if !NET9_0 public class InjectsExplicitChildValidator : AbstractValidator { public InjectsExplicitChildValidator() { #pragma warning disable CS0618 @@ -443,6 +444,7 @@ public InjectsExplicitChildValidatorCollection() { #pragma warning restore CS0618 } } +#endif public class BadAsyncModel { public int Id { get; set; } diff --git a/src/FluentValidation.Tests.AspNetCore/TypeFilterTests.cs b/src/FluentValidation.Tests.AspNetCore/TypeFilterTests.cs index 7f68f58..9556562 100644 --- a/src/FluentValidation.Tests.AspNetCore/TypeFilterTests.cs +++ b/src/FluentValidation.Tests.AspNetCore/TypeFilterTests.cs @@ -42,10 +42,10 @@ public async Task Finds_and_executes_validator() { fv.RegisterValidatorsFromAssemblyContaining(); }); }); - var result = await client.GetErrors("InjectsExplicitChildValidator"); + var result = await client.GetErrors("Test1"); // Validator was found and executed so field shouldn't be valid. - result.IsValidField("Child.Name").ShouldBeFalse(); + result.IsValidField("Name").ShouldBeFalse(); } @@ -54,14 +54,14 @@ public async Task Filters_types() { var client = _webApp.CreateClientWithServices(services => { services.AddMvc().AddNewtonsoftJson().AddFluentValidation(fv => { fv.RegisterValidatorsFromAssemblyContaining(scanResult => { - return scanResult.ValidatorType != typeof(InjectsExplicitChildValidator); + return scanResult.ValidatorType != typeof(TestModelValidator); }); }); }); - var result = await client.GetErrors("InjectsExplicitChildValidator"); + var result = await client.GetErrors("Test1"); // Should be valid as the validator was skipped. - result.IsValidField("Child.Name").ShouldBeTrue(); + result.IsValidField("Name").ShouldBeTrue(); } }