diff --git a/src/FluentValidation.DependencyInjectionExtensions/DependencyInjectionExtensions.cs b/src/FluentValidation.DependencyInjectionExtensions/DependencyInjectionExtensions.cs
deleted file mode 100644
index 202573ae2..000000000
--- a/src/FluentValidation.DependencyInjectionExtensions/DependencyInjectionExtensions.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-#region License
-// Copyright (c) .NET Foundation and contributors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// The latest version of this file can be found at https://github.com/FluentValidation/FluentValidation
-#endregion
-
-using FluentValidation.Internal;
-
-namespace FluentValidation;
-
-using System;
-using System.Collections.Generic;
-using Microsoft.Extensions.DependencyInjection;
-using Validators;
-
-///
-/// Extension methods for working with a Service Provider.
-///
-public static class DependencyInjectionExtensions {
-
- ///
- /// Gets the service provider associated with the validation context.
- ///
- ///
- ///
- ///
- [Obsolete("Storing a service provider within a ValidationContext is no longer supported. If you still require this functionality, you should manually store the service provider within context.RootContextData")]
- public static IServiceProvider GetServiceProvider(this IValidationContext context)
- => Get(context.RootContextData);
-
- ///
- /// Gets the service provider associated with the validation context.
- ///
- ///
- ///
- ///
- [Obsolete("Storing a service provider within a ValidationContext is no longer supported. If you still require this functionality, you should manually store the service provider within context.RootContextData")]
- public static IServiceProvider GetServiceProvider(this MessageBuilderContext context)
- => Get(context.ParentContext.RootContextData);
-
- private static IServiceProvider Get(IDictionary rootContextData) {
- if (rootContextData.TryGetValue("_FV_ServiceProvider", out var sp)) {
- if (sp is IServiceProvider serviceProvider) {
- return serviceProvider;
- }
- }
-
- throw new InvalidOperationException("The service provider has not been configured to work with FluentValidation. Making use of InjectValidator or GetServiceProvider is only supported when using the automatic MVC integration.");
- }
-
- ///
- /// Sets the service provider associated with the validation context.
- ///
- ///
- ///
- [Obsolete("Storing a service provider within a ValidationContext is no longer supported. If you still require this functionality, you should manually store the service provider within context.RootContextData")]
- public static void SetServiceProvider(this IValidationContext context, IServiceProvider serviceProvider) {
- context.RootContextData["_FV_ServiceProvider"] = serviceProvider;
- }
-
- ///
- /// Uses the Service Provider to inject the default validator for the property type.
- ///
- ///
- ///
- ///
- ///
- ///
- [Obsolete("The InjectValidator method is deprecated and will be removed in a future release. Please use Constructor Injection instead. See the following page for further details: https://github.com/FluentValidation/FluentValidation/issues/1960")]
- public static IRuleBuilderOptions InjectValidator(this IRuleBuilder ruleBuilder, params string[] ruleSets) {
- return ruleBuilder.InjectValidator((s, ctx) => s.GetService().GetValidator(), ruleSets);
- }
-
- ///
- /// Uses the Service Provider to inject the default validator for the property type.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- [Obsolete("The InjectValidator method is deprecated and will be removed in a future release. Please use Constructor Injection instead. See the following page for further details: https://github.com/FluentValidation/FluentValidation/issues/1960")]
- public static IRuleBuilderOptions InjectValidator(this IRuleBuilder ruleBuilder, Func, IValidator> callback, params string[] ruleSets) {
- var adaptor = new ChildValidatorAdaptor((context, _) => {
- var serviceProvider = context.GetServiceProvider();
- var validator = callback(serviceProvider, context);
- return validator;
- }, typeof(IValidator));
-
- adaptor.RuleSets = ruleSets;
- return ruleBuilder.SetAsyncValidator(adaptor);
- }
-}
diff --git a/src/FluentValidation.DependencyInjectionExtensions/FluentValidation.DependencyInjectionExtensions.csproj b/src/FluentValidation.DependencyInjectionExtensions/FluentValidation.DependencyInjectionExtensions.csproj
index 433a8cb6f..d66f29417 100644
--- a/src/FluentValidation.DependencyInjectionExtensions/FluentValidation.DependencyInjectionExtensions.csproj
+++ b/src/FluentValidation.DependencyInjectionExtensions/FluentValidation.DependencyInjectionExtensions.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/src/FluentValidation.Tests/CascadeModePropertiesTesterLegacy.cs b/src/FluentValidation.Tests/CascadeModePropertiesTesterLegacy.cs
deleted file mode 100644
index d2058601a..000000000
--- a/src/FluentValidation.Tests/CascadeModePropertiesTesterLegacy.cs
+++ /dev/null
@@ -1,187 +0,0 @@
-#region License
-// Copyright (c) .NET Foundation and contributors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// The latest version of this file can be found at https://github.com/FluentValidation/FluentValidation
-#endregion
-#pragma warning disable 618
-#pragma warning disable 1998
-
-namespace FluentValidation.Tests;
-
-using System;
-using Xunit;
-
-public class CascadeModePropertiesTesterLegacy : IDisposable {
- TestValidator _validator;
-
- public CascadeModePropertiesTesterLegacy() {
- SetBothGlobalCascadeModes(CascadeMode.Continue);
- _validator = new TestValidator();
- }
-
- public void Dispose() {
- SetBothGlobalCascadeModes(CascadeMode.Continue);
- }
-
- [Fact]
- public void Setting_global_default_CascadeMode_Stop_sets_both_rule_and_class_level_global_default_properties() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Stop;
-
- Assert.Equal(CascadeMode.Stop, ValidatorOptions.Global.DefaultRuleLevelCascadeMode);
- Assert.Equal(CascadeMode.Stop, ValidatorOptions.Global.DefaultClassLevelCascadeMode);
- }
-
- [Fact]
- public void Setting_global_default_CascadeMode_Continue_sets_both_rule_and_class_level_global_default_properties() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Stop;
- ValidatorOptions.Global.CascadeMode = CascadeMode.Continue;
-
- Assert.Equal(CascadeMode.Continue, ValidatorOptions.Global.DefaultRuleLevelCascadeMode);
- Assert.Equal(CascadeMode.Continue, ValidatorOptions.Global.DefaultClassLevelCascadeMode);
- }
-
- [Fact]
- public void Setting_global_default_CascadeMode_StopOnFirstFailure_sets_rule_Stop_and_class_Continue() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- Assert.Equal(CascadeMode.Stop, ValidatorOptions.Global.DefaultRuleLevelCascadeMode);
- Assert.Equal(CascadeMode.Continue, ValidatorOptions.Global.DefaultClassLevelCascadeMode);
- }
-
- [Fact]
- public void Setting_class_CascadeMode_Stop_sets_both_rule_and_class_level_properties() {
- _validator.CascadeMode = CascadeMode.Stop;
-
- Assert.Equal(CascadeMode.Stop, _validator.RuleLevelCascadeMode);
- Assert.Equal(CascadeMode.Stop, _validator.ClassLevelCascadeMode);
- }
-
- [Fact]
- public void Setting_class_CascadeMode_Continue_sets_both_rule_and_class_level_properties() {
- _validator.CascadeMode = CascadeMode.Stop;
- _validator.CascadeMode = CascadeMode.Continue;
-
- Assert.Equal(CascadeMode.Continue, _validator.RuleLevelCascadeMode);
- Assert.Equal(CascadeMode.Continue, _validator.ClassLevelCascadeMode);
- }
-
- [Fact]
- public void Setting_class_CascadeMode_StopOnFirstFailure_sets_rule_Stop_and_class_Continue() {
- _validator.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- Assert.Equal(CascadeMode.Stop, _validator.RuleLevelCascadeMode);
- Assert.Equal(CascadeMode.Continue, _validator.ClassLevelCascadeMode);
- }
-
- [Fact]
- public void Setting_global_DefaultRuleLevelCascadeMode_to_StopOnFirstFailure_sets_Stop() {
- ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.StopOnFirstFailure;
-
- Assert.Equal(CascadeMode.Stop, ValidatorOptions.Global.DefaultRuleLevelCascadeMode);
- }
-
- [Fact]
- public void Setting_global_DefaultClassLevelCascadeMode_to_StopOnFirstFailure_sets_Stop() {
- ValidatorOptions.Global.DefaultClassLevelCascadeMode = CascadeMode.StopOnFirstFailure;
-
- Assert.Equal(CascadeMode.Stop, ValidatorOptions.Global.DefaultClassLevelCascadeMode);
- }
-
- [Fact]
- public void Setting_class_RuleLevelCascadeMode_to_StopOnFirstFailure_sets_Stop() {
- _validator.RuleLevelCascadeMode = CascadeMode.StopOnFirstFailure;
-
- Assert.Equal(CascadeMode.Stop, _validator.RuleLevelCascadeMode);
- }
-
- [Fact]
- public void Setting_class_ClassLevelCascadeMode_to_StopOnFirstFailure_sets_Stop() {
- _validator.ClassLevelCascadeMode = CascadeMode.StopOnFirstFailure;
-
- Assert.Equal(CascadeMode.Stop, _validator.ClassLevelCascadeMode);
- }
-
- [Fact]
- public void Global_default_CascadeMode_Get_returns_Stop_when_both_Stop() {
- SetBothGlobalCascadeModes(CascadeMode.Stop);
-
- Assert.Equal(CascadeMode.Stop, ValidatorOptions.Global.CascadeMode);
- }
-
- [Fact]
- public void Global_default_CascadeMode_Get_returns_Continue_when_both_Continue() {
- SetBothGlobalCascadeModes(CascadeMode.Stop);
- SetBothGlobalCascadeModes(CascadeMode.Continue);
-
- Assert.Equal(CascadeMode.Continue, ValidatorOptions.Global.CascadeMode);
- }
-
- [Fact]
- public void Global_default_CascadeMode_Get_returns_StopOnFirstFailure_when_class_Continue_and_rule_Stop() {
- ValidatorOptions.Global.DefaultClassLevelCascadeMode = CascadeMode.Continue;
- ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.Stop;
-
- Assert.Equal(CascadeMode.StopOnFirstFailure, ValidatorOptions.Global.CascadeMode);
- }
-
- [Fact]
- public void Global_default_CascadeMode_Get_throws_exception_when_class_Stop_and_rule_Continue() {
- ValidatorOptions.Global.DefaultClassLevelCascadeMode = CascadeMode.Stop;
- ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.Continue;
-
- Assert.ThrowsAny(() => ValidatorOptions.Global.CascadeMode);
- }
-
- [Fact]
- public void Class_CascadeMode_Get_returns_Stop_when_both_Stop() {
- SetBothValidatorCascadeModes(CascadeMode.Stop);
-
- Assert.Equal(CascadeMode.Stop, _validator.CascadeMode);
- }
-
- [Fact]
- public void Class_CascadeMode_Get_returns_Continue_when_both_Continue() {
- SetBothValidatorCascadeModes(CascadeMode.Stop);
- SetBothValidatorCascadeModes(CascadeMode.Continue);
-
- Assert.Equal(CascadeMode.Continue, _validator.CascadeMode);
- }
-
- [Fact]
- public void Class_CascadeMode_Get_returns_StopOnFirstFailure_when_class_Continue_and_rule_Stop() {
- _validator.ClassLevelCascadeMode = CascadeMode.Continue;
- _validator.RuleLevelCascadeMode = CascadeMode.Stop;
-
- Assert.Equal(CascadeMode.StopOnFirstFailure, _validator.CascadeMode);
- }
-
- [Fact]
- public void Class_CascadeMode_Get_throws_exception_when_class_Stop_and_rule_Continue() {
- _validator.ClassLevelCascadeMode = CascadeMode.Stop;
- _validator.RuleLevelCascadeMode = CascadeMode.Continue;
-
- Assert.ThrowsAny(() => _validator.CascadeMode);
- }
-
- private void SetBothValidatorCascadeModes(CascadeMode cascadeMode) {
- _validator.ClassLevelCascadeMode = cascadeMode;
- _validator.RuleLevelCascadeMode = cascadeMode;
- }
-
- private static void SetBothGlobalCascadeModes(CascadeMode cascadeMode) {
- ValidatorOptions.Global.DefaultClassLevelCascadeMode = cascadeMode;
- ValidatorOptions.Global.DefaultRuleLevelCascadeMode = cascadeMode;
- }
-}
diff --git a/src/FluentValidation.Tests/CascadingFailuresTester.cs b/src/FluentValidation.Tests/CascadingFailuresTester.cs
index b907b00d3..9c704681f 100644
--- a/src/FluentValidation.Tests/CascadingFailuresTester.cs
+++ b/src/FluentValidation.Tests/CascadingFailuresTester.cs
@@ -117,14 +117,6 @@ public class CascadingFailuresTester : IDisposable {
results.Errors.Count.ShouldEqual(1);
}
- [Fact]
- public void Validation_stops_on_first_failure_when_globaldefault_both_Continue_and_ruleleveloverride_Stop_legacy() {
- SetBothGlobalCascadeModes(CascadeMode.Continue);
- _validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).NotNull().Equal("Foo");
- var results = _validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
[Fact]
public void Validation_continues_to_second_validator_when_first_validator_succeeds_and_globaldefault_both_Stop() {
SetBothGlobalCascadeModes(CascadeMode.Stop);
@@ -216,15 +208,6 @@ public class CascadingFailuresTester : IDisposable {
results.Errors.Count.ShouldEqual(1);
}
- [Fact]
- public void Validation_stops_on_failure_when_classlevel_Continue_and_ruleleveldefault_Continue_and_ruleleveloverride_Stop_legacy() {
- SetBothValidatorCascadeModes(CascadeMode.Continue);
-
- _validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).NotNull().Equal("Foo");
- var results = _validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
[Fact]
public void Cascade_mode_can_be_set_after_validator_instantiated() {
_validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
@@ -321,15 +304,6 @@ public class CascadingFailuresTester : IDisposable {
results.Errors.Count.ShouldEqual(1);
}
- [Fact]
- public async Task Validation_stops_on_first_Failure_when_globaldefault_both_Continue_and_ruleleveloverride_Stop_async_legacy() {
- SetBothGlobalCascadeModes(CascadeMode.Continue);
- _validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await _validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
-
[Fact]
public async Task Validation_stops_on_first_Failure_when_globaldefault_both_Continue_and_ruleleveloverride_Stop_async_and_async_validator_is_invoked_synchronously() {
SetBothGlobalCascadeModes(CascadeMode.Continue);
@@ -338,14 +312,6 @@ public class CascadingFailuresTester : IDisposable {
results.Errors.Count.ShouldEqual(1);
}
- [Fact]
- public async Task Validation_stops_on_first_Failure_when_globaldefault_both_Continue_and_ruleleveloverride_Stop_async_and_async_validator_is_invoked_synchronously_legacy() {
- SetBothGlobalCascadeModes(CascadeMode.Continue);
- _validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).NotNull().Equal("Foo");
- var results = await _validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
[Fact]
public async Task Validation_continues_to_second_validator_when_first_validator_succeeds_and_globaldefault_both_Stop_async() {
SetBothGlobalCascadeModes(CascadeMode.Stop);
@@ -465,15 +431,6 @@ public class CascadingFailuresTester : IDisposable {
results.Errors.Count.ShouldEqual(1);
}
- [Fact]
- public async Task Validation_stops_on_failure_when_classlevel_Continue_and_ruleleveldefault_Continue_and_ruleleveloverride_Stop_async_legacy() {
- SetBothValidatorCascadeModes(CascadeMode.Continue);
-
- _validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await _validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
[Fact]
public async Task Cascade_mode_can_be_set_after_validator_instantiated_async() {
_validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
@@ -490,6 +447,14 @@ public class CascadingFailuresTester : IDisposable {
results.Errors.Count.ShouldEqual(1);
}
+ [Fact]
+ public void CascadeMode_values_should_correspond_to_correct_integers() {
+ // 12.0 removed the "StopOnFirstFailure" option which was value 1.
+ // For compatibility, "Stop" should still equate to 2, rather than being renumbered to 1.
+ Assert.Equal(0, (int)CascadeMode.Continue);
+ Assert.Equal(2, (int)CascadeMode.Stop);
+ }
+
private void SetBothValidatorCascadeModes(CascadeMode cascadeMode) {
_validator.ClassLevelCascadeMode = cascadeMode;
_validator.RuleLevelCascadeMode = cascadeMode;
diff --git a/src/FluentValidation.Tests/CascadingFailuresTesterLegacy.cs b/src/FluentValidation.Tests/CascadingFailuresTesterLegacy.cs
deleted file mode 100644
index 241b461c6..000000000
--- a/src/FluentValidation.Tests/CascadingFailuresTesterLegacy.cs
+++ /dev/null
@@ -1,364 +0,0 @@
-#region License
-// Copyright (c) .NET Foundation and contributors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// The latest version of this file can be found at https://github.com/FluentValidation/FluentValidation
-#endregion
-#pragma warning disable 618
-#pragma warning disable 1998
-
-namespace FluentValidation.Tests;
-
-using System;
-using System.Threading.Tasks;
-using Xunit;
-
-public class CascadingFailuresTesterLegacy : IDisposable {
- TestValidator validator;
-
- public CascadingFailuresTesterLegacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Continue;
- validator = new TestValidator();
- }
-
- public void Dispose() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Continue;
- }
-
- [Fact]
- public void Validation_continues_on_failure() {
- validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public void Validation_stops_on_first_failure() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Stop;
-
- validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public void Validation_stops_on_first_failure_legacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public void Validation_continues_on_failure_when_set_to_Stop_globally_and_overriden_at_rule_level() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Stop;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Continue).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public void Validation_continues_on_failure_when_set_to_Stop_globally_and_overriden_at_rule_level_legacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Continue).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public void Validation_stops_on_first_Failure_when_set_to_Continue_globally_and_overriden_at_rule_level() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Continue;
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Stop).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public void Validation_stops_on_first_Failure_when_set_to_Continue_globally_and_overriden_at_rule_level_legacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Continue;
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public void Validation_continues_to_second_validator_when_first_validator_succeeds_and_cascade_set_to_stop() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Stop;
- validator.RuleFor(x => x.Surname).NotNull().Length(2, 10);
- var result = validator.Validate(new Person() {Surname = "x"});
- result.IsValid.ShouldBeFalse();
- }
-
- [Fact]
- public void Validation_continues_to_second_validator_when_first_validator_succeeds_and_cascade_set_to_stop_legacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.StopOnFirstFailure;
- validator.RuleFor(x => x.Surname).NotNull().Length(2, 10);
- var result = validator.Validate(new Person() {Surname = "x"});
- result.IsValid.ShouldBeFalse();
- }
-
- [Fact]
- public void Validation_stops_on_first_failure_when_set_to_StopOnFirstFailure_at_validator_level() {
- validator.CascadeMode = CascadeMode.Stop;
-
- validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
- validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public void Validation_stops_on_first_failure_when_set_to_StopOnFirstFailure_at_validator_level_legacy() {
- validator.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public void Validation_continues_when_set_to_Continue_at_validator_level() {
- validator.CascadeMode = CascadeMode.Continue;
-
- validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public void Validation_continues_on_failure_when_set_to_Stop_at_validator_level_and_overriden_at_rule_level() {
- validator.CascadeMode = CascadeMode.Stop;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Continue).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public void Validation_continues_on_failure_when_set_to_StopOnFirstFailure_at_validator_level_and_overriden_at_rule_level_legacy() {
- validator.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Continue).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public void Validation_stops_on_failure_when_set_to_Continue_and_overriden_at_rule_level() {
- validator.CascadeMode = CascadeMode.Continue;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Stop).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public void Validation_stops_on_failure_when_set_to_Continue_and_overriden_at_rule_level_legacy() {
- validator.CascadeMode = CascadeMode.Continue;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).NotNull().Equal("Foo");
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public void Cascade_mode_can_be_set_after_validator_instantiated() {
- validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
- validator.CascadeMode = CascadeMode.Stop;
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public void Cascade_mode_can_be_set_after_validator_instantiated_legacy() {
- validator.RuleFor(x => x.Surname).NotNull().Equal("Foo");
- validator.CascadeMode = CascadeMode.StopOnFirstFailure;
- var results = validator.Validate(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Validation_continues_on_failure_async() {
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public async Task Validation_stops_on_first_failure_async() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Stop;
-
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Validation_stops_on_first_failure_async_legacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Validation_continues_on_failure_when_set_to_Stop_globally_and_overriden_at_rule_level_async() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Stop;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Continue).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public async Task Validation_continues_on_failure_when_set_to_Stop_globally_and_overriden_at_rule_level_async_legacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Continue).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public async Task Validation_stops_on_first_Failure_when_set_to_Continue_globally_and_overriden_at_rule_level_async() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Continue;
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Stop).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Validation_stops_on_first_Failure_when_set_to_Continue_globally_and_overriden_at_rule_level_async_legacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Continue;
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
-
- [Fact]
- public async Task Validation_stops_on_first_Failure_when_set_to_Continue_globally_and_overriden_at_rule_level_and_async_validator_is_invoked_synchronously() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Continue;
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Stop).NotNull().Equal("Foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Validation_stops_on_first_Failure_when_set_to_Continue_globally_and_overriden_at_rule_level_and_async_validator_is_invoked_synchronously_legacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Continue;
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).NotNull().Equal("Foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Validation_continues_to_second_validator_when_first_validator_succeeds_and_cascade_set_to_stop_async() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.Stop;
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var result = await validator.ValidateAsync(new Person {Surname = "x"});
- result.IsValid.ShouldBeFalse();
- }
-
- [Fact]
- public async Task Validation_continues_to_second_validator_when_first_validator_succeeds_and_cascade_set_to_stop_async_legacy() {
- ValidatorOptions.Global.CascadeMode = CascadeMode.StopOnFirstFailure;
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var result = await validator.ValidateAsync(new Person {Surname = "x"});
- result.IsValid.ShouldBeFalse();
- }
-
- [Fact]
- public async Task Validation_stops_on_first_failure_when_set_to_StopOnFirstFailure_at_validator_level_async() {
- validator.CascadeMode = CascadeMode.Stop;
-
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact] public async Task Validation_stops_on_first_failure_when_set_to_StopOnFirstFailure_at_validator_level_async_legacy() {
- validator.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Validation_continues_when_set_to_Continue_at_validator_level_async() {
- validator.CascadeMode = CascadeMode.Continue;
-
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public async Task Validation_continues_on_failure_when_set_to_StopOnFirstFailure_at_validator_level_and_overriden_at_rule_level_async() {
- validator.CascadeMode = CascadeMode.Stop;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Continue).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public async Task Validation_continues_on_failure_when_set_to_StopOnFirstFailure_at_validator_level_and_overriden_at_rule_level_async_legacy() {
- validator.CascadeMode = CascadeMode.StopOnFirstFailure;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Continue).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(2);
- }
-
- [Fact]
- public async Task Validation_stops_on_failure_when_set_to_Continue_and_overriden_at_rule_level_async() {
- validator.CascadeMode = CascadeMode.Continue;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.Stop).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Validation_stops_on_failure_when_set_to_Continue_and_overriden_at_rule_level_async_legacy() {
- validator.CascadeMode = CascadeMode.Continue;
-
- validator.RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Cascade_mode_can_be_set_after_validator_instantiated_async() {
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- validator.CascadeMode = CascadeMode.Stop;
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-
- [Fact]
- public async Task Cascade_mode_can_be_set_after_validator_instantiated_async_legacy() {
- validator.RuleFor(x => x.Surname).MustAsync(async (x, c) => x != null).MustAsync(async (x, c) => x == "foo");
- validator.CascadeMode = CascadeMode.StopOnFirstFailure;
- var results = await validator.ValidateAsync(new Person());
- results.Errors.Count.ShouldEqual(1);
- }
-}
diff --git a/src/FluentValidation.Tests/ChainedValidationTester.cs b/src/FluentValidation.Tests/ChainedValidationTester.cs
index 3c584af9a..135efcfa6 100644
--- a/src/FluentValidation.Tests/ChainedValidationTester.cs
+++ b/src/FluentValidation.Tests/ChainedValidationTester.cs
@@ -177,9 +177,7 @@ public class ChainedValidationTester {
public class DepartmentValidator : AbstractValidator {
public DepartmentValidator() {
-#pragma warning disable 618
- CascadeMode = CascadeMode.StopOnFirstFailure;
-#pragma warning restore 618
+ RuleLevelCascadeMode = CascadeMode.Stop;
RuleFor(x => x.Manager).NotNull();
RuleFor(x => x.Assistant.Surname).NotEqual(x => x.Manager.Surname).When(x => x.Assistant != null && x.Manager.Surname != null);
}
diff --git a/src/FluentValidation.Tests/ForEachRuleTests.cs b/src/FluentValidation.Tests/ForEachRuleTests.cs
index 39ccc0478..2b889e698 100644
--- a/src/FluentValidation.Tests/ForEachRuleTests.cs
+++ b/src/FluentValidation.Tests/ForEachRuleTests.cs
@@ -220,12 +220,10 @@ await ExclusiveDelay(1)
[Fact]
public void Can_use_cascade_with_RuleForEach() {
var validator = new InlineValidator();
-#pragma warning disable 618
validator.RuleForEach(x => x.NickNames)
- .Cascade(CascadeMode.StopOnFirstFailure)
+ .Cascade(CascadeMode.Stop)
.NotNull()
.NotEqual("foo");
-#pragma warning restore 618
var result = validator.Validate(new Person {NickNames = new string[] {null}});
result.Errors.Count.ShouldEqual(1);
diff --git a/src/FluentValidation/AbstractValidator.cs b/src/FluentValidation/AbstractValidator.cs
index 5a317776b..4161ff8eb 100644
--- a/src/FluentValidation/AbstractValidator.cs
+++ b/src/FluentValidation/AbstractValidator.cs
@@ -38,59 +38,6 @@ public abstract class AbstractValidator : IValidator, IEnumerable _classLevelCascadeMode = () => ValidatorOptions.Global.DefaultClassLevelCascadeMode;
private Func _ruleLevelCascadeMode = () => ValidatorOptions.Global.DefaultRuleLevelCascadeMode;
-#pragma warning disable 618
- ///
- ///
- /// Gets a single mode value representing the default values of
- ///
- /// and ., based on the same logic as used when setting
- /// this property as described below.
- ///
- ///
- /// Sets the values of
- /// and .
- ///
- ///
- /// If set to or , then both properties are set
- /// to that value.
- ///
- ///
- /// If set to the deprecated ,
- /// then
- /// is set to , and
- /// is set to .
- /// This results in the same behaviour as before this property was deprecated.
- ///
- ///
- [Obsolete($"Use {nameof(ClassLevelCascadeMode)} and/or {nameof(RuleLevelCascadeMode)} instead. " +
- "CascadeMode will be removed in a future release. " +
- "For more details, see https://docs.fluentvalidation.net/en/latest/cascade.html")]
- public CascadeMode CascadeMode {
- get {
- if (ClassLevelCascadeMode == RuleLevelCascadeMode) {
- return ClassLevelCascadeMode;
- }
- else if (ClassLevelCascadeMode == CascadeMode.Continue && RuleLevelCascadeMode == CascadeMode.Stop) {
- return CascadeMode.StopOnFirstFailure;
- }
- else {
- throw new Exception(
- $"There is no conversion to a single {nameof(CascadeMode)} value from the current combination of " +
- $"{nameof(ClassLevelCascadeMode)} and {nameof(RuleLevelCascadeMode)}. " +
- $"Please use these properties instead of the deprecated {nameof(CascadeMode)} going forward.");
- }
- }
- set {
- ClassLevelCascadeMode = value == CascadeMode.StopOnFirstFailure
- ? CascadeMode.Continue
- : value;
-
- RuleLevelCascadeMode = value == CascadeMode.StopOnFirstFailure
- ? CascadeMode.Stop
- : value;
- }
- }
-
///
///
/// Sets the cascade behaviour in between rules in this validator.
@@ -106,17 +53,10 @@ public abstract class AbstractValidator : IValidator, IEnumerablewithin individual rules is controlled by
/// .
///
- ///
- /// This cannot be set to the deprecated .
- /// . Attempting to do so it will actually
- /// result in being used.
- ///
///
public CascadeMode ClassLevelCascadeMode {
get => _classLevelCascadeMode();
- set => _classLevelCascadeMode = value == CascadeMode.StopOnFirstFailure
- ? () => CascadeMode.Stop
- : () => value;
+ set => _classLevelCascadeMode = () => value;
}
///
@@ -134,20 +74,12 @@ public abstract class AbstractValidator : IValidator, IEnumerable
/// Note that cascade behaviour between rules is controlled by .
///
- ///
- /// This cannot be set to the deprecated .
- /// . Attempting to do so it will actually
- /// result in being used.
- ///
///
public CascadeMode RuleLevelCascadeMode {
get => _ruleLevelCascadeMode();
- set => _ruleLevelCascadeMode = value == CascadeMode.StopOnFirstFailure
- ? () => CascadeMode.Stop
- : () => value;
+ set => _ruleLevelCascadeMode = () => value;
}
-#pragma warning restore 618
ValidationResult IValidator.Validate(IValidationContext context) {
context.Guard("Cannot pass null to Validate", nameof(context));
return Validate(ValidationContext.GetFromNonGenericContext(context));
diff --git a/src/FluentValidation/Enums.cs b/src/FluentValidation/Enums.cs
index e08ffcd21..766392430 100644
--- a/src/FluentValidation/Enums.cs
+++ b/src/FluentValidation/Enums.cs
@@ -28,23 +28,13 @@ public enum CascadeMode {
/// When a rule/validator fails, execution continues to the next rule/validator.
/// For more information, see the methods/properties that accept this enum as a parameter.
///
- Continue,
- ///
- /// For more information, see the methods/properties that accept this enum as a parameter.
- ///
- [Obsolete(
- $"The behaviour of {nameof(StopOnFirstFailure)} has been replaced by use of the " +
- $"separate validator-level properties {nameof(AbstractValidator