Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

12.0 CI #2009

Draft
wants to merge 35 commits into
base: main
Choose a base branch
from
Draft

12.0 CI #2009

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
cfa20cb
Drop netstandard2 and net5 #1975 #1704
JeremySkinner Sep 14, 2022
96feb0b
Disable package validation until 12.0 branch merged
JeremySkinner Sep 14, 2022
77efb3b
Remove deprecated DI extensions and deprecated cascade mode options
JeremySkinner Sep 14, 2022
c04d9de
Remove reference to System.Threading.Tasks.Extensions now we no longe…
JeremySkinner Sep 16, 2022
80ca798
Fix merge issue and disable package validation for now
JeremySkinner Nov 18, 2022
33c379b
Test helper cleanup
JeremySkinner Nov 18, 2022
f3a4ada
Update assembly version
JeremySkinner Nov 18, 2022
58bce78
12.0 upgrade guide and other minor docs tweaks
JeremySkinner Nov 23, 2022
1f94f29
Updates to upgrade guide
JeremySkinner Dec 15, 2022
1263fed
Move to .net 6 as our minimum supported platform
JeremySkinner Feb 19, 2023
9b2688e
Update the 12.0 the upgrade guide
JeremySkinner Feb 19, 2023
630e904
Update uses of old guard methods
JeremySkinner Feb 19, 2023
8277bd4
Add missing null checks
JeremySkinner Feb 19, 2023
a0d9e13
Replace ScalePrecisionValidator with PrecisionScaleValidator and tidy up
JeremySkinner Feb 20, 2023
6c0e705
Remove deprecated Transform methods
JeremySkinner Feb 20, 2023
f8b9557
Remove the ability to disable the root model null check.
JeremySkinner Feb 20, 2023
c2a0981
Replace custom delgate type with func
JeremySkinner Feb 21, 2023
ddb1cc8
Remove unused Transform-related methods
JeremySkinner Feb 21, 2023
688840f
Remove use of Guard
JeremySkinner Mar 15, 2023
e572ce5
Merge branch 'main' into 12.x-dev
JeremySkinner Aug 17, 2023
f8ab85b
Bump version
JeremySkinner Aug 17, 2023
9952137
Merge branch 'main' into 12.x-dev
JeremySkinner Nov 24, 2023
ec8042f
Upgrade to .net 8
JeremySkinner Nov 24, 2023
e808290
Merge branch 'main' into 12.x-dev
JeremySkinner Nov 24, 2023
28be97d
Update supported versions
JeremySkinner Nov 24, 2023
d4c8868
Merge branch 'main' into 12.x-dev
JeremySkinner Nov 24, 2023
2ba521d
Update index.rst
JeremySkinner Dec 2, 2023
4730f26
Update upgrading-to-12.md
JeremySkinner Dec 2, 2023
4fc5b1e
Update upgrading-to-12.md
JeremySkinner Dec 2, 2023
4547e39
Update upgrading-to-12.md
JeremySkinner Dec 2, 2023
2dbf0e5
Merge branch 'main' into 12.x-dev
JeremySkinner Feb 3, 2024
a6199dc
Add support for dependent rules for custom rules #2170
JeremySkinner Nov 24, 2023
24805a2
Update changelog
JeremySkinner Feb 3, 2024
4054037
Improved AccessorCache<T> (#2200)
jscarle Mar 13, 2024
14cef8c
Merge branch 'main' into 12.x-dev
JeremySkinner Apr 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions Changelog.txt
@@ -1,3 +1,10 @@
12.0.0 -
Drops support for netstandard2.0, netstandard2.1 and .net 5. Minimum supported platform is now .net 6.
Add support for dependent rules for custom rules (#2170)
Removes deprecated DI extensions
Removes deprecated transform methods (#2027)
Remove the ability to disable the root-model null check (#2069)

11.9.1 - 23 Apr 2024
Fix issue with CascadeMode on child validators (#2207)

Expand Down
43 changes: 6 additions & 37 deletions docs/cascade.md
Expand Up @@ -25,11 +25,6 @@ The two cascade modes are:
- `Continue` (the default) - always invokes all rules in a validator class, or all validators in a rule, depending on where it is used (see below).
- `Stop` - stops executing a validator class as soon as a rule fails, or stops executing a rule as soon as a validator fails, depending on where it is used (see below).

```eval_rst
.. warning::
The Stop option is only available in FluentValidation 9.1 and newer. In older versions, you can use StopOnFirstFailure instead (see "Stop vs StopOnFirstFailure").
```

If you have a validator class with multiple rules, and would like this `Stop` behaviour to be set for all of your rules, you could do e.g.:
```csharp
RuleFor(x => x.Forename).Cascade(CascadeMode.Stop).NotNull().NotEqual("foo");
Expand Down Expand Up @@ -60,45 +55,19 @@ To set the default cascade modes at rule-level and/or validator class-level glob

```eval_rst
.. warning::
The RuleLevelCascadeMode, ClassLevelCascadeMode, and their global defaults are only available in FluentValidation 11 and newer. See below.
The RuleLevelCascadeMode, ClassLevelCascadeMode, and their global defaults are only available in FluentValidation 11 and newer.
```

## Introduction of RuleLevelCascadeMode and ClassLevelCascadeMode (and deprecation of CascadeMode)
## Introduction of RuleLevelCascadeMode and ClassLevelCascadeMode (and removal of CascadeMode)
The `AbstractValidator.RuleLevelCascadeMode`, `AbstractValidator.ClassLevelCascadeMode`, and their global defaults were introduced in FluentValidation 11

In older versions, there was only one property controlling cascade modes: `AbstractValidator.CascadeMode`. Changing this value would set the cascade mode at both validator class-level and rule-level. Therefore, for example, if you wanted to have the above-described functionality where you create a list of validation errors, by stopping on failure at rule-level to avoid crashes, but continuing at validator class-level, you would need to set `AbstractValidator.CascadeMode` to `Continue`, and then repeat `Cascade(CascadeMode.Stop)` on every rule chain (or use the deprecated `StopOnFirstFailure` with a warning; see "Stop vs StopOnFirstFailure").
In older versions, there was only one property controlling cascade modes: `AbstractValidator.CascadeMode`. Changing this value would set the cascade mode at both validator class-level and rule-level. Therefore, for example, if you wanted to have the above-described functionality where you create a list of validation errors, by stopping on failure at rule-level to avoid crashes, but continuing at validator class-level, you would need to set `AbstractValidator.CascadeMode` to `Continue`, and then repeat `Cascade(CascadeMode.Stop)` on every rule chain.

The new properties enable finer control of the cascade mode at the different levels, with less repetition.

```eval_rst
.. warning::
In FluentValidation11, there are _no_ breaking changes to cascade modes. The `AbstractValidator.CascadeMode` property (and its global default property) are still present, and they function exactly the same as they did before, but they do so by setting / returning the values of `RuleLevelCascadeMode` and `ClassLevelCascadeMode`, as opposed to being used by the code directly.

However, `AbstractValidator.CascadeMode` and its global default are deprecated, and will be removed in a future version. To convert to the new properties, see `the upgrade guide <upgrading-to-11.html#cascade-mode-changes>`_.
```

## Stop vs StopOnFirstFailure

In FluentValidation 9.0 and older, the `CascadeMode.StopOnFirstFailure` option was used to provide control over the default cascade mode at rule-level, but its use was not intuitive. There was no `CascadeMode.Stop` option.

With `StopOnFirstFailure`, the following would provide the example behavior described previously (stop any rule if it fails, but then continue executing at validator class-level, so that all rules are executed):

```csharp
CascadeMode = CascadeMode.StopOnFirstFailure;

RuleFor(x => x.Forename).NotNull().NotEqual("foo");
RuleFor(x => x.MiddleNames).NotNull().NotEqual("foo");
RuleFor(x => x.Surname).NotNull().NotEqual("foo");
The `CascadeMode` property was deprecated in FluentValidation 11 and removed in FluentValidation 12. The `RuleLevelCascadeMode` and `ClassLevelCascadeMode` properties should be used instead.

To convert to the new properties, see `the upgrade guide <upgrading-to-11.html#cascade-mode-changes>`_.
```
If they all fail, you will get three validation errors. That is the equivalent of doing

```csharp
RuleFor(x => x.Forename).Cascade(CascadeMode.StopOnFirstFailure).NotNull().NotEqual("foo");
RuleFor(x => x.MiddleNames).Cascade(CascadeMode.StopOnFirstFailure).NotNull().NotEqual("foo");
RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).NotNull().NotEqual("foo");
```
This behaviour caused a lot of confusion over the years, so the `Stop` option was introduced in FluentValidation 9.1. Using `Stop` instead of `StopOnFirstFailure`, _any_ failure at all would stop execution, so only the first failure result would be returned.

The `Stop` option was introduced rather than changing the behaviour of `StopOnFirstFailure` as this would've been a very subtle breaking change, so we thought it was best to maintain the existing behaviour while adding a new option. `StopOnFirstFailure` was marked as Obsolete in FluentValidation 9.1, and generated compiler warnings.

See also the FluentValidation 11 changes described above, that further change how the above code would be written. `StopOnFirstFailure` is still available as of version 11 and has no breaking changes to how it functions. However, in a future version, it _will_ be removed, now that it's possible to replicate its behavior using the new properties `AbstractValidator.RuleLevelCascadeMode` and `AbstractValidator.ClassLevelCascadeMode`.
10 changes: 3 additions & 7 deletions docs/index.rst
Expand Up @@ -8,16 +8,11 @@ FluentValidation

FluentValidation is a .NET library for building strongly-typed validation rules.

FluentValidation 11 supports the following platforms:
FluentValidation 12 supports the following platforms:

* .NET Core 3.1
* .NET 5
* .NET 6
* .NET 7
* .NET 8
* `.NET Standard 2.0 <https://docs.microsoft.com/en-us/dotnet/standard/net-standard>`_

For automatic validation with ASP.NET, FluentValidation supports ASP.NET running on .NET Core 3.1, .NET 5 or .NET 6.

If you're new to using FluentValidation, check out the :doc:`start` page.

Expand Down Expand Up @@ -127,7 +122,8 @@ Example
:maxdepth: 1
:caption: Upgrading

upgrading-to-12
upgrading-to-11
upgrading-to-10
upgrading-to-9
upgrading-to-8
upgrading-to-8
2 changes: 1 addition & 1 deletion docs/upgrading-to-11.md
Expand Up @@ -85,7 +85,7 @@ RuleLevelCascadeMode = CascadeMode.Stop;

...or their global default equivalents.

See [this page in the documentation](https://docs.fluentvalidation.net/en/latest/conditions.html#setting-the-cascade-mode) for details of how cascade modes work and the reasons for this change.
See [this page in the documentation](https://docs.fluentvalidation.net/en/latest/conditions.html#setting-the-cascade-mode) for details of how cascade modes work.

As `StopOnFirstFailure` is deprecated and scheduled for removal, it cannot be assigned to either of the two new `AbstractValidator` properties or their global equivalents (it still can be assigned to the also-deprecated `AbstractValidator.CascadeMode`). Attempting to set the new properties to `StopOnFirstFailure` will simply result in `Stop` being used instead.

Expand Down
94 changes: 94 additions & 0 deletions docs/upgrading-to-12.md
@@ -0,0 +1,94 @@
# 12.0 Upgrade Guide

### Introduction

FluentValidation 12.0 is a major release that included several breaking changes. Please review this document carefully before upgrading from FluentValidation 11.x to 12.

The main goal of this release was removal of deprecated code and removal of support for obsolete platforms. There are no new features in this release.

### Changes in supported platforms

- .NET 5 is no longer supported (Microsoft's support for .NET 5 ended in November 2022)
- .NET Core 3.1 is no longer supported (Microsoft's support for .NET Core 3.1 ended in December 2022)
- .NET Standard is no longer support
- .NET 6 is the minimum supported version

If you still need .NET Standard 2.0 compatibility then you will need to continue to use FluentValidation 11.x and only upgrade to FluentValidation 12 once you've moved to a more modern version of .NET.

### Removal of the Transform and TransformForEach methods

The `Transform` and `TransformForEach` methods deprecated in 11.x have been removed. For details on how to migrate see [https://github.com/FluentValidation/FluentValidation/issues/2072](https://github.com/FluentValidation/FluentValidation/issues/2072)

### Removal of CascadeMode.StopOnFirstFailure

The `StopOnFirstFailure` cascade option was deprecated in FluentValidation 11.0 and has now been removed, along with the `AbstractValidator.CascadeMode` and `ValidatorOptions.Global.CascadeMode` properties which were also deprecated in 11.0.

If were previously setting `ValidatorOptions.Global.CascadeMode` to `Continue` or `Stop`, you can simply replace this with the following:

```csharp
ValidatorOptions.Global.DefaultClassLevelCascadeMode = CascadeMode.<YourCurrentValue>;
ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.<YourCurrentValue>;
```

If you were previously setting it to `StopOnFirstFailure`, replace it with the following:

```csharp
ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.Stop;
```

Similarly, if you were previously setting `AbstractValidator.CascadeMode` to `Continue` or `Stop`, replace this with the following:

```csharp
ClassLevelCascadeMode = CascadeMode.<YourCurrentValue>;
RuleLevelCascadeMode = CascadeMode.<YourCurrentValue>;
```

If you were previously setting it to `StopOnFirstFailure`, replace it with the following:

```csharp
ClassLevelCascadeMode = CascadeMode.Continue;
RuleLevelCascadeMode = CascadeMode.Stop;
```

If you were calling `.Cascade(CascadeMode.StopOnFirstFailure)` in a rule chain, replace `StopOnFirstFailure` with `Stop`.

### Removal of InjectValidator and related methods

The `InjectValidator` method was deprecated in 11.x and removed in 12.0.

This method allowed you to implicitly inject a child validator from the ASP.NET Service Provider:

```csharp
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator()
{
RuleFor(x => x.Address).InjectValidator();
}
}
```

Assuming that the address property is of type `Address`, the above code would attempt to resolve an `IValidator<Address>` and use this to validator the `Address` property. This method can only be used when working with ASP.NET MVC's auto-validation feature and cannot be used in other contexts.

Instead of using `InjectValidator`, you should instead use a more traditional constructor injection approach, which is not just limited to ASP.NET MVC:

```csharp
public class PersonValidator : AbstractValidator<Person>
{
public PersonValidator(IValidator<Address> addressValidator)
{
RuleFor(x => x.Address).SetValidator(addressValidator);
}
}
```

### Removal of AbstractValidator.EnsureInstanceNotNull

In previous versions of FluentValidation it was possible to override the `AbstractValidator.EnsureInstanceNotNull` method to disable FluentValidation's root-model null check. The ability to do this was deprecated in 11.5.x and has now been removed. For further details please see [https://github.com/FluentValidation/FluentValidation/issues/2069](https://github.com/FluentValidation/FluentValidation/issues/2069)


### Other breaking API changes

- The `ITestValidationContinuation` interface now exposes a `MatchedFailures` property (as well as the existing `UnmatchedFailures`)
- The `ShouldHaveAnyValidationError` method has been renamed to `ShouldHaveValidationErrors`
- `ShouldNotHaveAnyValidationErrors` and `ShouldHaveValidationErrors` are now instance methods on `TestValidationResult`, instead of extension methods.
3 changes: 1 addition & 2 deletions src/CommonAssemblyInfo.cs
@@ -1,4 +1,3 @@
using System;
using System.Reflection;

[assembly : AssemblyVersion("11.0.0.0")]
[assembly : AssemblyVersion("12.0.0.0")]
6 changes: 3 additions & 3 deletions src/Directory.Build.props
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<VersionPrefix>11.9.1</VersionPrefix>
<VersionSuffix></VersionSuffix>
<VersionPrefix>12.0.0</VersionPrefix>
<VersionSuffix>preview1</VersionSuffix>
<!-- Use CI build number as version suffix (if defined) -->
<!--<VersionSuffix Condition="'$(GITHUB_RUN_NUMBER)'!=''">ci-$(GITHUB_RUN_NUMBER)</VersionSuffix>-->
<Authors>Jeremy Skinner</Authors>
Expand All @@ -17,7 +17,7 @@
<NeutralLanguage>en</NeutralLanguage>
<AssemblyOriginatorKeyFile>$(MSBuildProjectDirectory)/../FluentValidation-Release.snk</AssemblyOriginatorKeyFile>
<PackageOutputPath>$(MSBuildProjectDirectory)/../../.build/packages</PackageOutputPath>
<PackageValidationBaselineVersion>11.0.0</PackageValidationBaselineVersion>
<PackageValidationBaselineVersion>12.0.0</PackageValidationBaselineVersion>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\logo\fluent-validation-icon.png" Pack="true" PackagePath="" />
Expand Down

This file was deleted.

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1</TargetFrameworks>
<TargetFramework>net6.0</TargetFramework>
<AssemblyName>FluentValidation.DependencyInjectionExtensions</AssemblyName>
<PackageId>FluentValidation.DependencyInjectionExtensions</PackageId>
<Product>FluentValidation.DependencyInjectionExtensions</Product>
Expand All @@ -18,10 +18,11 @@
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<ContinuousIntegrationBuild Condition="'$(Configuration)'=='Release'">true</ContinuousIntegrationBuild>
<EnablePackageValidation>false</EnablePackageValidation>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs" Link="CommonAssemblyInfo.cs" />
<None Include="README.md" Pack="true" PackagePath="\"/>
<None Include="README.md" Pack="true" PackagePath="\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Dependencyinjection.Abstractions" Version="2.1.0" />
Expand Down