Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 158 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
[*]
charset = utf-8-bom
end_of_line = crlf
trim_trailing_whitespace = false
insert_final_newline = false
indent_style = space
indent_size = 4
max_line_length = 960

[*.yml]
indent_size = 2

# Microsoft .NET properties
csharp_new_line_before_members_in_object_initializers = false
csharp_preferred_modifier_order = public, private, protected, internal, file, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async, required:suggestion
csharp_space_after_cast = true
csharp_style_prefer_utf8_string_literals = true:suggestion
csharp_style_var_elsewhere = true:suggestion
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
dotnet_naming_rule.interfaces_rule.import_to_resharper = True
dotnet_naming_rule.interfaces_rule.resharper_description = Interfaces
dotnet_naming_rule.interfaces_rule.resharper_guid = a7a3339e-4e89-4319-9735-a9dc4cb74cc7
dotnet_naming_rule.interfaces_rule.severity = warning
dotnet_naming_rule.interfaces_rule.style = i_upper_camel_case_style
dotnet_naming_rule.interfaces_rule.symbols = interfaces_symbols
dotnet_naming_rule.private_constants_rule.import_to_resharper = True
dotnet_naming_rule.private_constants_rule.resharper_description = Constant fields (private)
dotnet_naming_rule.private_constants_rule.resharper_guid = 236f7aa5-7b06-43ca-bf2a-9b31bfcff09a
dotnet_naming_rule.private_constants_rule.severity = warning
dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style
dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols
dotnet_naming_rule.private_instance_fields_rule.import_to_resharper = True
dotnet_naming_rule.private_instance_fields_rule.resharper_description = Instance fields (private)
dotnet_naming_rule.private_instance_fields_rule.resharper_guid = 4a98fdf6-7d98-4f5a-afeb-ea44ad98c70c
dotnet_naming_rule.private_instance_fields_rule.severity = warning
dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols
dotnet_naming_rule.private_static_fields_rule.import_to_resharper = True
dotnet_naming_rule.private_static_fields_rule.resharper_description = Static fields (private)
dotnet_naming_rule.private_static_fields_rule.resharper_guid = f9fce829-e6f4-4cb2-80f1-5497c44f51df
dotnet_naming_rule.private_static_fields_rule.severity = warning
dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols
dotnet_naming_rule.private_static_readonly_rule.import_to_resharper = True
dotnet_naming_rule.private_static_readonly_rule.resharper_description = Static readonly fields (private)
dotnet_naming_rule.private_static_readonly_rule.resharper_guid = 15b5b1f1-457c-4ca6-b278-5615aedc07d3
dotnet_naming_rule.private_static_readonly_rule.severity = warning
dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style
dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols
dotnet_naming_rule.type_parameters_rule.import_to_resharper = True
dotnet_naming_rule.type_parameters_rule.resharper_description = Type parameters
dotnet_naming_rule.type_parameters_rule.resharper_guid = 2c62818f-621b-4425-adc9-78611099bfcb
dotnet_naming_rule.type_parameters_rule.severity = warning
dotnet_naming_rule.type_parameters_rule.style = t_upper_camel_case_style
dotnet_naming_rule.type_parameters_rule.symbols = type_parameters_symbols
dotnet_naming_rule.unity_serialized_field_rule.import_to_resharper = True
dotnet_naming_rule.unity_serialized_field_rule.resharper_description = Unity serialized field
dotnet_naming_rule.unity_serialized_field_rule.resharper_guid = 5f0fdb63-c892-4d2c-9324-15c80b22a7ef
dotnet_naming_rule.unity_serialized_field_rule.severity = warning
dotnet_naming_rule.unity_serialized_field_rule.style = lower_camel_case_style
dotnet_naming_rule.unity_serialized_field_rule.symbols = unity_serialized_field_symbols
dotnet_naming_style.i_upper_camel_case_style.capitalization = pascal_case
dotnet_naming_style.i_upper_camel_case_style.required_prefix = I
dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
dotnet_naming_style.t_upper_camel_case_style.capitalization = pascal_case
dotnet_naming_style.t_upper_camel_case_style.required_prefix = T
dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case
dotnet_naming_symbols.interfaces_symbols.applicable_accessibilities = *
dotnet_naming_symbols.interfaces_symbols.applicable_kinds = interface
dotnet_naming_symbols.interfaces_symbols.resharper_applicable_kinds = interface
dotnet_naming_symbols.interfaces_symbols.resharper_required_modifiers = any
dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field
dotnet_naming_symbols.private_constants_symbols.required_modifiers = const
dotnet_naming_symbols.private_constants_symbols.resharper_applicable_kinds = constant_field
dotnet_naming_symbols.private_constants_symbols.resharper_required_modifiers = any
dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.private_instance_fields_symbols.resharper_applicable_kinds = field,readonly_field
dotnet_naming_symbols.private_instance_fields_symbols.resharper_required_modifiers = instance
dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static
dotnet_naming_symbols.private_static_fields_symbols.resharper_applicable_kinds = field
dotnet_naming_symbols.private_static_fields_symbols.resharper_required_modifiers = static
dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = readonly,static
dotnet_naming_symbols.private_static_readonly_symbols.resharper_applicable_kinds = readonly_field
dotnet_naming_symbols.private_static_readonly_symbols.resharper_required_modifiers = static
dotnet_naming_symbols.type_parameters_symbols.applicable_accessibilities = *
dotnet_naming_symbols.type_parameters_symbols.applicable_kinds = type_parameter
dotnet_naming_symbols.type_parameters_symbols.resharper_applicable_kinds = type_parameter
dotnet_naming_symbols.type_parameters_symbols.resharper_required_modifiers = any
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_accessibilities = *
dotnet_naming_symbols.unity_serialized_field_symbols.applicable_kinds =
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_applicable_kinds = unity_serialised_field
dotnet_naming_symbols.unity_serialized_field_symbols.resharper_required_modifiers = instance
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
dotnet_style_qualification_for_event = false:suggestion
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion

# ReSharper properties
resharper_autodetect_indent_settings = true
resharper_formatter_off_tag = @formatter:off
resharper_formatter_on_tag = @formatter:on
resharper_formatter_tags_enabled = true
resharper_place_accessorholder_attribute_on_same_line = false
resharper_place_accessor_attribute_on_same_line = false
resharper_place_field_attribute_on_same_line = false
resharper_space_within_single_line_array_initializer_braces = false
resharper_use_indent_from_vs = false

# ReSharper inspection severities
resharper_arrange_redundant_parentheses_highlighting = hint
resharper_arrange_this_qualifier_highlighting = hint
resharper_arrange_type_member_modifiers_highlighting = hint
resharper_arrange_type_modifiers_highlighting = hint
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
resharper_built_in_type_reference_style_highlighting = hint
resharper_mvc_action_not_resolved_highlighting = warning
resharper_mvc_area_not_resolved_highlighting = warning
resharper_mvc_controller_not_resolved_highlighting = warning
resharper_mvc_masterpage_not_resolved_highlighting = warning
resharper_mvc_partial_view_not_resolved_highlighting = warning
resharper_mvc_template_not_resolved_highlighting = warning
resharper_mvc_view_component_not_resolved_highlighting = warning
resharper_mvc_view_component_view_not_resolved_highlighting = warning
resharper_mvc_view_not_resolved_highlighting = warning
resharper_razor_assembly_not_resolved_highlighting = warning
resharper_redundant_base_qualifier_highlighting = warning
resharper_suggest_var_or_type_built_in_types_highlighting = hint
resharper_suggest_var_or_type_elsewhere_highlighting = hint
resharper_suggest_var_or_type_simple_types_highlighting = hint
resharper_web_config_module_not_resolved_highlighting = warning
resharper_web_config_type_not_resolved_highlighting = warning
resharper_web_config_wrong_module_highlighting = warning

[{*.har,*.jsb2,*.jsb3,*.json,*.jsonc,*.postman_collection,*.postman_collection.json,*.postman_environment,*.postman_environment.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,.ws-context,jest.config}]
indent_style = space
indent_size = 2

[*.scss]
indent_style = space
indent_size = 2

[*.{appxmanifest,asax,ascx,aspx,axaml,blockshader,build,c,c++,c++m,cc,ccm,cginc,compute,cp,cpp,cppm,cs,cshtml,cu,cuh,cxx,cxxm,dtd,fs,fsi,fsscript,fsx,fx,fxh,h,h++,hh,hlsl,hlsli,hlslinc,hp,hpp,hxx,icc,inc,inl,ino,ipp,ixx,master,ml,mli,mpp,mq4,mq5,mqh,mxx,nuspec,paml,razor,resw,resx,shader,shaderFoundry,skin,tcc,tpp,urtshader,usf,ush,uxml,vb,xaml,xamlx,xoml,xsd}]
indent_style = space
indent_size = 4
tab_width = 4
10 changes: 4 additions & 6 deletions .github/workflows/Build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ env:
JAVA_VERSION: 17
JAVA_DISTRIBUTION: microsoft
DOTNET_VERSION: |
3.1.x
6.0.x
7.0.x
8.0.x
9.0.x
10.0.x
DOTNET_BUILD_CONFIGURATION: Release
SONAR_PATH: .\.sonar\scanner
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Expand All @@ -29,18 +27,18 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Set up Java
uses: actions/setup-java@v3
uses: actions/setup-java@v5
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRIBUTION }}

- name: Set up .NET
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/Release.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: FluentValidation.AutoValidation [Release]

env:
DOTNET_VERSION: 9.0.x
DOTNET_VERSION: 10.0.x
DOTNET_BUILD_CONFIGURATION: Release
DOTNET_PACKAGES_OUTPUT_DIRECTORY: .nuget
NUGET_SOURCE: https://api.nuget.org/v3/index.json
Expand All @@ -18,12 +18,12 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Set up .NET
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>8.0</LangVersion>
<NoWarn>NU1701</NoWarn>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
</PropertyGroup>

<PropertyGroup>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
<AssemblyName>SharpGrip.FluentValidation.AutoValidation.Endpoints</AssemblyName>
<PackageId>SharpGrip.FluentValidation.AutoValidation.Endpoints</PackageId>
<Title>SharpGrip FluentValidation AutoValidation Endpoints</Title>
Expand All @@ -18,7 +17,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.102">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ public static class ServiceCollectionExtensions
/// <param name="serviceCollection">The service collection.</param>
/// <param name="autoValidationEndpointsConfiguration">The configuration delegate used to configure the FluentValidation AutoValidation Endpoints validation.</param>
/// <returns>The service collection.</returns>
public static IServiceCollection AddFluentValidationAutoValidation(this IServiceCollection serviceCollection,
Action<AutoValidationEndpointsConfiguration>? autoValidationEndpointsConfiguration = null)
public static IServiceCollection AddFluentValidationAutoValidation(this IServiceCollection serviceCollection, Action<AutoValidationEndpointsConfiguration>? autoValidationEndpointsConfiguration = null)
{
var configuration = new AutoValidationEndpointsConfiguration();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
using FluentValidation;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SharpGrip.FluentValidation.AutoValidation.Endpoints.Interceptors;
using SharpGrip.FluentValidation.AutoValidation.Endpoints.Results;
using SharpGrip.FluentValidation.AutoValidation.Shared.Extensions;

namespace SharpGrip.FluentValidation.AutoValidation.Endpoints.Filters
{
public class FluentValidationAutoValidationEndpointFilter : IEndpointFilter
public class FluentValidationAutoValidationEndpointFilter(ILogger<FluentValidationAutoValidationEndpointFilter> logger) : IEndpointFilter
{
public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext endpointFilterInvocationContext, EndpointFilterDelegate next)

Check warning on line 14 in FluentValidation.AutoValidation.Endpoints/src/Filters/FluentValidationAutoValidationEndpointFilter.cs

View workflow job for this annotation

GitHub Actions / build

Rename parameter 'endpointFilterInvocationContext' to 'context' to match the interface declaration. (https://rules.sonarsource.com/csharp/RSPEC-927)

Check warning on line 14 in FluentValidation.AutoValidation.Endpoints/src/Filters/FluentValidationAutoValidationEndpointFilter.cs

View workflow job for this annotation

GitHub Actions / build

Refactor this method to reduce its Cognitive Complexity from 23 to the 15 allowed. (https://rules.sonarsource.com/csharp/RSPEC-3776)

Check warning on line 14 in FluentValidation.AutoValidation.Endpoints/src/Filters/FluentValidationAutoValidationEndpointFilter.cs

View workflow job for this annotation

GitHub Actions / build

Rename parameter 'endpointFilterInvocationContext' to 'context' to match the interface declaration. (https://rules.sonarsource.com/csharp/RSPEC-927)

Check warning on line 14 in FluentValidation.AutoValidation.Endpoints/src/Filters/FluentValidationAutoValidationEndpointFilter.cs

View workflow job for this annotation

GitHub Actions / build

Refactor this method to reduce its Cognitive Complexity from 23 to the 15 allowed. (https://rules.sonarsource.com/csharp/RSPEC-3776)

Check warning on line 14 in FluentValidation.AutoValidation.Endpoints/src/Filters/FluentValidationAutoValidationEndpointFilter.cs

View workflow job for this annotation

GitHub Actions / build

Rename parameter 'endpointFilterInvocationContext' to 'context' to match the interface declaration. (https://rules.sonarsource.com/csharp/RSPEC-927)

Check warning on line 14 in FluentValidation.AutoValidation.Endpoints/src/Filters/FluentValidationAutoValidationEndpointFilter.cs

View workflow job for this annotation

GitHub Actions / build

Refactor this method to reduce its Cognitive Complexity from 23 to the 15 allowed. (https://rules.sonarsource.com/csharp/RSPEC-3776)
{
var serviceProvider = endpointFilterInvocationContext.HttpContext.RequestServices;

Expand All @@ -18,45 +19,60 @@
{
if (argument != null && argument.GetType().IsCustomType() && serviceProvider.GetValidator(argument.GetType()) is IValidator validator)
{
// ReSharper disable once SuspiciousTypeConversion.Global
logger.LogDebug("Starting validation for argument of type '{Type}'.", argument.GetType().Name);

var validatorInterceptor = validator as IValidatorInterceptor;
var globalValidationInterceptor = serviceProvider.GetService<IGlobalValidationInterceptor>();

IValidationContext validationContext = new ValidationContext<object>(argument);

if (validatorInterceptor != null)
{
validationContext = validatorInterceptor.BeforeValidation(endpointFilterInvocationContext, validationContext) ?? validationContext;
logger.LogDebug("Invoking validator interceptor BeforeValidation for argument '{Argument}'.", argument.GetType().Name);
validationContext = await validatorInterceptor.BeforeValidation(endpointFilterInvocationContext, validationContext, endpointFilterInvocationContext.HttpContext.RequestAborted) ?? validationContext;
}

if (globalValidationInterceptor != null)
{
validationContext = globalValidationInterceptor.BeforeValidation(endpointFilterInvocationContext, validationContext) ?? validationContext;
logger.LogDebug("Invoking global validation interceptor BeforeValidation for argument '{Argument}'.", argument.GetType().Name);
validationContext = await globalValidationInterceptor.BeforeValidation(endpointFilterInvocationContext, validationContext, endpointFilterInvocationContext.HttpContext.RequestAborted) ?? validationContext;
}

var validationResult = await validator.ValidateAsync(validationContext, endpointFilterInvocationContext.HttpContext.RequestAborted);

if (validatorInterceptor != null)
{
validationResult = validatorInterceptor.AfterValidation(endpointFilterInvocationContext, validationContext) ?? validationResult;
logger.LogDebug("Invoking validator interceptor AfterValidation for argument '{Argument}'.", argument.GetType().Name);
validationResult = await validatorInterceptor.AfterValidation(endpointFilterInvocationContext, validationContext, validationResult, endpointFilterInvocationContext.HttpContext.RequestAborted) ?? validationResult;
}

if (globalValidationInterceptor != null)
{
validationResult = globalValidationInterceptor.AfterValidation(endpointFilterInvocationContext, validationContext) ?? validationResult;
logger.LogDebug("Invoking global validation interceptor AfterValidation for argument '{Argument}'.", argument.GetType().Name);
validationResult = await globalValidationInterceptor.AfterValidation(endpointFilterInvocationContext, validationContext, validationResult, endpointFilterInvocationContext.HttpContext.RequestAborted) ?? validationResult;
}

if (!validationResult.IsValid)
{
logger.LogDebug("Validation result not valid for argument '{Argument}': {ErrorCount} validation error(s) found.", argument.GetType().Name, validationResult.Errors.Count);

var fluentValidationAutoValidationResultFactory = serviceProvider.GetService<IFluentValidationAutoValidationResultFactory>();

logger.LogDebug("Creating result for path '{Path}'.", endpointFilterInvocationContext.HttpContext.Request.Path);

if (fluentValidationAutoValidationResultFactory != null)
{
logger.LogTrace("Creating result for path '{Path}' using a custom result factory.", endpointFilterInvocationContext.HttpContext.Request.Path);

return fluentValidationAutoValidationResultFactory.CreateResult(endpointFilterInvocationContext, validationResult);
}

logger.LogTrace("Creating result for path '{Path}' using the default result factory.", endpointFilterInvocationContext.HttpContext.Request.Path);

return new FluentValidationAutoValidationDefaultResultFactory().CreateResult(endpointFilterInvocationContext, validationResult);
}

logger.LogDebug("Validation result valid for argument '{Argument}'.", argument.GetType().Name);
}
}

Expand Down
Loading
Loading