├── .github
└── workflows
│ ├── Build.yaml
│ └── Release.yaml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── Directory.Build.props
├── FluentValidation.AutoValidation.Endpoints
├── FluentValidation.AutoValidation.Endpoints.csproj
└── src
│ ├── Configuration
│ └── AutoValidationEndpointsConfiguration.cs
│ ├── Extensions
│ ├── EndpointRouteExtensions.cs
│ └── ServiceCollectionExtensions.cs
│ ├── Filters
│ └── FluentValidationAutoValidationEndpointFilter.cs
│ ├── Interceptors
│ ├── IGlobalValidationInterceptor.cs
│ └── IValidatorInterceptor.cs
│ └── Results
│ ├── FluentValidationAutoValidationDefaultResultFactory.cs
│ └── IFluentValidationAutoValidationResultFactory.cs
├── FluentValidation.AutoValidation.Mvc
├── FluentValidation.AutoValidation.Mvc.csproj
└── src
│ ├── Attributes
│ ├── AutoValidateAlwaysAttribute.cs
│ ├── AutoValidateNeverAttribute.cs
│ ├── AutoValidationAttribute.cs
│ └── FluentValidationAutoValidationAttribute.cs
│ ├── Configuration
│ └── AutoValidationMvcConfiguration.cs
│ ├── Enums
│ └── ValidationStrategy.cs
│ ├── Extensions
│ └── ServiceCollectionExtensions.cs
│ ├── Filters
│ └── FluentValidationAutoValidationActionFilter.cs
│ ├── Interceptors
│ ├── IGlobalValidationInterceptor.cs
│ └── IValidatorInterceptor.cs
│ ├── Results
│ ├── FluentValidationAutoValidationDefaultResultFactory.cs
│ └── IFluentValidationAutoValidationResultFactory.cs
│ └── Validation
│ ├── FluentValidationAutoValidationObjectModelValidator.cs
│ └── FluentValidationAutoValidationValidationVisitor.cs
├── FluentValidation.AutoValidation.Shared
├── FluentValidation.AutoValidation.Shared.csproj
└── src
│ └── Extensions
│ ├── ParameterInfoExtensions.cs
│ ├── ServiceProviderExtensions.cs
│ ├── TypeExtensions.cs
│ └── ValidationResultExtensions.cs
├── FluentValidation.AutoValidation.sln
├── LICENSE
├── README.md
└── Tests
├── FluentValidation.AutoValidation.Tests.csproj
└── src
├── FluentValidation.AutoValidation.Endpoints
├── Configuration
│ └── AutoValidationEndpointsConfigurationTest.cs
├── Extensions
│ └── ServiceCollectionExtensionsTest.cs
├── Filters
│ └── FluentValidationAutoValidationEndpointFilterTest.cs
└── Results
│ └── FluentValidationAutoValidationDefaultResultFactoryTest.cs
├── FluentValidation.AutoValidation.Mvc
├── Configuration
│ └── AutoValidationMvcConfigurationTest.cs
├── Extensions
│ └── ServiceCollectionExtensionsTest.cs
├── Filters
│ └── FluentValidationAutoValidationActionFilterTest.cs
├── Results
│ └── FluentValidationAutoValidationDefaultResultFactoryTest.cs
└── Validation
│ ├── FluentValidationAutoValidationObjectModelValidatorTest.cs
│ └── FluentValidationAutoValidationValidationVisitorTest.cs
└── FluentValidation.AutoValidation.Shared
└── Extensions
├── ServiceProviderExtensionsTest.cs
├── TypeExtensionsTest.cs
└── ValidationResultExtensionsTest.cs
/.github/workflows/Build.yaml:
--------------------------------------------------------------------------------
1 | name: FluentValidation.AutoValidation [Build]
2 |
3 | env:
4 | JAVA_VERSION: 17
5 | JAVA_DISTRIBUTION: microsoft
6 | DOTNET_VERSION: |
7 | 3.1.x
8 | 6.0.x
9 | 7.0.x
10 | 8.0.x
11 | 9.0.x
12 | DOTNET_BUILD_CONFIGURATION: Release
13 | SONAR_PATH: .\.sonar\scanner
14 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
15 | SONAR_HOST: https://sonarcloud.io
16 | SONAR_ORGANIZATION: sharpgrip
17 | SONAR_PROJECT: SharpGrip_FluentValidation.AutoValidation
18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
19 |
20 | on:
21 | workflow_dispatch:
22 | push:
23 | branches:
24 | - "**"
25 |
26 | jobs:
27 | build:
28 | runs-on: windows-latest
29 |
30 | steps:
31 | - name: Checkout
32 | uses: actions/checkout@v3
33 | with:
34 | fetch-depth: 0
35 |
36 | - name: Set up Java
37 | uses: actions/setup-java@v3
38 | with:
39 | java-version: ${{ env.JAVA_VERSION }}
40 | distribution: ${{ env.JAVA_DISTRIBUTION }}
41 |
42 | - name: Set up .NET
43 | uses: actions/setup-dotnet@v3
44 | with:
45 | dotnet-version: ${{ env.DOTNET_VERSION }}
46 |
47 | - name: Install dotnet-coverage
48 | shell: powershell
49 | run: dotnet tool install --global dotnet-coverage
50 |
51 | - name: Install SonarCloud scanner
52 | shell: powershell
53 | run: |
54 | New-Item -Path ${{ env.SONAR_PATH }} -ItemType Directory -Force
55 | dotnet tool update dotnet-sonarscanner --tool-path ${{ env.SONAR_PATH }}
56 |
57 | - name: Build solution
58 | run: dotnet build -c ${{ env.DOTNET_BUILD_CONFIGURATION }} /warnaserror /nowarn:CS0612,CS0618
59 |
60 | - name: Test solution
61 | run: dotnet test --no-build -c ${{ env.DOTNET_BUILD_CONFIGURATION }} --verbosity normal
62 |
63 | - name: Cleanup solution
64 | run: dotnet clean
65 |
66 | - name: Analyze solution
67 | shell: powershell
68 | run: |
69 | .\.sonar\scanner\dotnet-sonarscanner begin /k:"${{ env.SONAR_PROJECT }}" /o:"${{ env.SONAR_ORGANIZATION }}" /d:sonar.token="${{ env.SONAR_TOKEN }}" /d:sonar.host.url="${{ env.SONAR_HOST }}" /d:sonar.cs.vscoveragexml.reportsPaths=coverage.xml
70 | dotnet build -c ${{ env.DOTNET_BUILD_CONFIGURATION }}
71 | dotnet-coverage collect "dotnet test -c ${{ env.DOTNET_BUILD_CONFIGURATION }}" -f xml -o "coverage.xml"
72 | .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="${{ env.SONAR_TOKEN }}"
--------------------------------------------------------------------------------
/.github/workflows/Release.yaml:
--------------------------------------------------------------------------------
1 | name: FluentValidation.AutoValidation [Release]
2 |
3 | env:
4 | DOTNET_VERSION: 9.0.x
5 | DOTNET_BUILD_CONFIGURATION: Release
6 | DOTNET_PACKAGES_OUTPUT_DIRECTORY: .nuget
7 | NUGET_SOURCE: https://api.nuget.org/v3/index.json
8 | NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
9 |
10 | on:
11 | push:
12 | tags:
13 | - "*"
14 |
15 | jobs:
16 | build:
17 | runs-on: ubuntu-latest
18 |
19 | steps:
20 | - name: Checkout
21 | uses: actions/checkout@v3
22 | with:
23 | fetch-depth: 0
24 |
25 | - name: Set up .NET
26 | uses: actions/setup-dotnet@v3
27 | with:
28 | dotnet-version: ${{ env.DOTNET_VERSION }}
29 |
30 | - name: Pack packages
31 | run: dotnet pack --configuration ${{ env.DOTNET_BUILD_CONFIGURATION }} --output "${{ env.DOTNET_PACKAGES_OUTPUT_DIRECTORY }}"
32 |
33 | - name: Push packages
34 | run: dotnet nuget push "${{ env.DOTNET_PACKAGES_OUTPUT_DIRECTORY }}/*.nupkg" --source ${{ env.NUGET_SOURCE }} --api-key ${{ env.NUGET_API_KEY }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .nuget/
3 | NuGet/
4 | [Oo]bj/
5 | [Bb]in/
6 | .DS_Store
7 | *.DotSettings.user
8 | .vs/
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at info@sharpgrip.net. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | enable
4 | 8.0
5 | NU1701
6 | true
7 | true
8 | snupkg
9 |
10 |
11 |
12 | 1.5.0
13 | SharpGrip
14 | SharpGrip
15 | SharpGrip
16 | MIT
17 | README.md
18 | https://sharpgrip.net
19 | https://github.com/SharpGrip/FluentValidation.AutoValidation
20 | git
21 |
22 |
23 |
24 | true
25 |
26 |
--------------------------------------------------------------------------------
/FluentValidation.AutoValidation.Endpoints/FluentValidation.AutoValidation.Endpoints.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SharpGrip.FluentValidation.AutoValidation.Endpoints
5 |
6 |
7 |
8 | net7.0;net8.0;net9.0
9 | SharpGrip.FluentValidation.AutoValidation.Endpoints
10 | SharpGrip.FluentValidation.AutoValidation.Endpoints
11 | SharpGrip FluentValidation AutoValidation Endpoints
12 | SharpGrip FluentValidation AutoValidation Endpoints is an extension of the FluentValidation library enabling automatic asynchronous validation in minimal APIs (endpoints).
13 | sharpgrip;validation;fluent-validation;endpoints;minimal-api
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | all
23 | runtime; build; native; contentfiles; analyzers; buildtransitive
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/FluentValidation.AutoValidation.Endpoints/src/Configuration/AutoValidationEndpointsConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Http.HttpResults;
3 | using SharpGrip.FluentValidation.AutoValidation.Endpoints.Results;
4 |
5 | namespace SharpGrip.FluentValidation.AutoValidation.Endpoints.Configuration
6 | {
7 | public class AutoValidationEndpointsConfiguration
8 | {
9 | ///
10 | /// Holds the overridden result factory. This property is meant for infrastructure and should not be used by application code.
11 | ///
12 | public Type? OverriddenResultFactory { get; private set; }
13 |
14 | ///
15 | /// Overrides the default result factory with a custom result factory. Custom result factories are required to implement .
16 | /// The default result factory returns the validation errors wrapped in a object.
17 | ///
18 | ///
19 | /// The custom result factory implementing .
20 | public void OverrideDefaultResultFactoryWith() where TResultFactory : IFluentValidationAutoValidationResultFactory
21 | {
22 | OverriddenResultFactory = typeof(TResultFactory);
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/FluentValidation.AutoValidation.Endpoints/src/Extensions/EndpointRouteExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Http;
3 | using Microsoft.AspNetCore.Routing;
4 | using SharpGrip.FluentValidation.AutoValidation.Endpoints.Filters;
5 |
6 | namespace SharpGrip.FluentValidation.AutoValidation.Endpoints.Extensions
7 | {
8 | public static class EndpointRouteExtensions
9 | {
10 | ///
11 | /// Adds asynchronous minimal API automatic validation to the specified .
12 | ///
13 | /// The route handler builder.
14 | /// The route handler builder.
15 | public static RouteHandlerBuilder AddFluentValidationAutoValidation(this RouteHandlerBuilder routeHandlerBuilder)
16 | {
17 | routeHandlerBuilder.AddEndpointFilter();
18 |
19 | return routeHandlerBuilder;
20 | }
21 |
22 | ///
23 | /// Adds asynchronous minimal API Fluent Validation automatic validation to the specified .
24 | ///
25 | /// The route group builder.
26 | /// The route group builder.
27 | public static RouteGroupBuilder AddFluentValidationAutoValidation(this RouteGroupBuilder routeGroupBuilder)
28 | {
29 | routeGroupBuilder.AddEndpointFilter();
30 |
31 | return routeGroupBuilder;
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/FluentValidation.AutoValidation.Endpoints/src/Extensions/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using Microsoft.Extensions.DependencyInjection.Extensions;
4 | using SharpGrip.FluentValidation.AutoValidation.Endpoints.Configuration;
5 | using SharpGrip.FluentValidation.AutoValidation.Endpoints.Results;
6 |
7 | namespace SharpGrip.FluentValidation.AutoValidation.Endpoints.Extensions
8 | {
9 | public static class ServiceCollectionExtensions
10 | {
11 | ///
12 | /// Adds asynchronous Endpoints Fluent Validation automatic validation to the specified .
13 | ///
14 | /// The service collection.
15 | /// The configuration delegate used to configure the FluentValidation AutoValidation Endpoints validation.
16 | /// The service collection.
17 | public static IServiceCollection AddFluentValidationAutoValidation(this IServiceCollection serviceCollection,
18 | Action? autoValidationEndpointsConfiguration = null)
19 | {
20 | var configuration = new AutoValidationEndpointsConfiguration();
21 |
22 | if (autoValidationEndpointsConfiguration != null)
23 | {
24 | autoValidationEndpointsConfiguration.Invoke(configuration);
25 | serviceCollection.Configure(autoValidationEndpointsConfiguration);
26 | }
27 |
28 | // Add the default result factory.
29 | serviceCollection.AddScoped();
30 |
31 | // If the custom result factory is not null, replace the default result factory with the overridden result factory.
32 | if (configuration.OverriddenResultFactory != null)
33 | {
34 | serviceCollection.Replace(new ServiceDescriptor(typeof(IFluentValidationAutoValidationResultFactory), configuration.OverriddenResultFactory, ServiceLifetime.Scoped));
35 | }
36 |
37 | return serviceCollection;
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/FluentValidation.AutoValidation.Endpoints/src/Filters/FluentValidationAutoValidationEndpointFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using FluentValidation;
3 | using Microsoft.AspNetCore.Http;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using SharpGrip.FluentValidation.AutoValidation.Endpoints.Interceptors;
6 | using SharpGrip.FluentValidation.AutoValidation.Endpoints.Results;
7 | using SharpGrip.FluentValidation.AutoValidation.Shared.Extensions;
8 |
9 | namespace SharpGrip.FluentValidation.AutoValidation.Endpoints.Filters
10 | {
11 | public class FluentValidationAutoValidationEndpointFilter : IEndpointFilter
12 | {
13 | public async ValueTask