CoreDX.Extensions.AspNetCore.Validation 1.3.5

dotnet add package CoreDX.Extensions.AspNetCore.Validation --version 1.3.5                
NuGet\Install-Package CoreDX.Extensions.AspNetCore.Validation -Version 1.3.5                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CoreDX.Extensions.AspNetCore.Validation" Version="1.3.5" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CoreDX.Extensions.AspNetCore.Validation --version 1.3.5                
#r "nuget: CoreDX.Extensions.AspNetCore.Validation, 1.3.5"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install CoreDX.Extensions.AspNetCore.Validation as a Cake Addin
#addin nuget:?package=CoreDX.Extensions.AspNetCore.Validation&version=1.3.5

// Install CoreDX.Extensions.AspNetCore.Validation as a Cake Tool
#tool nuget:?package=CoreDX.Extensions.AspNetCore.Validation&version=1.3.5                

About

Add async model validation services for Microsoft Asp.Net Core MVC and Minimal-APIs.

How to Use

  1. ServiceCollection
using Microsoft.AspNetCore.Mvc;

services
    .AddMvc()
    // Add async data annotations validation services.
    .AddAsyncDataAnnotations();

// Or
services
    .AddMvcCore()
    // Add data annotations validation services frist when using mvc core.
    .AddDataAnnotations()
    // Add async data annotations validation services.
    .AddAsyncDataAnnotations();
  1. MVC and Razor pages
using Microsoft.AspNetCore.Mvc;

public class MyController : ControllerBase
{
    public async Task Post(CustomModel input)
    {
        // TryValidateModel(input) // This will ignore async validation attributes.
        await this.TryValidateModelAsync(input);
    }
}

public class MyModel : PageModel
{
    public CustomModel Input { get; set; }

    public async Task OnPostAsync()
    {
        // TryValidateModel(Input) // This will ignore async validation attributes.
        await this.TryValidateModelAsync(Input);
    }
}
  1. Minimal-APIs's data annotations localization (only for .NET 7.0+)
using Microsoft.AspNetCore.Http;

// Add a localization services like this (package: CoreDX.Extensions.Localization.EntityFrameworkCore)
services
    .AddEntityFrameworkCoreLocalization<ApplicationDbContext, ApplicationLocalizationRecord>(static options =>
    {
        options.ResourcesPath = "Resources";
        options.CreateLocalizationResourcesIfNotExist = true;
    });

// Or use localization services from MVC
services
    .AddMvc()
    .AddDataAnnotationsLocalization();

// Then add Minimal-APIs's data annotations localization services
services.AddEndpointParameterDataAnnotationsLocalization(static options =>
{
    // Add custom validation attribute's localization arguments adapter.
    options.Adapters.Add(new MyCustomAsyncAttributeAdapter());
});
  1. Minimal-APIs's data annotations validation (only for .NET 7.0+)
using Microsoft.AspNetCore.Http;

public class MyCustomAsyncAttribute : AsyncValidationAttribute
{
    public string MyArgument1 { get; set; } = null!;

    public string MyArgument2 { get; set; } = null!;

    public string MyArgument3 { get; set; } = null!;

    public override ValueTask<bool> IsValidAsync(object? value, CancellationToken cancellationToken = default)
    {
        return ValueTask.FromResult(false);
    }
}

public class MyCustomAsyncAttributeAdapter : AttributeAdapterBase<MyCustomAsyncAttribute>
{
    protected override object[]? GetLocalizationArgumentsInternal(MyCustomAsyncAttribute attribute)
    {
        return [attribute.MyArgument1, attribute.MyArgument2, attribute.MyArgument3];
    }
}

public class CustomModel
{
    [Display(Name = nameof(Text1))]
    [Required]
    [StringLength(42)]
    public string Text1 { get; set; } = null!;

    [MyCustomAsync(MyArgument1 = "val1", MyArgument2 = "val2", MyArgument3 = "val3", ErrorMessage = "The field {0} must valid {1} and {2} and {3}.")]
    public string? Text2 { get; set; }

    [Required]
    public InnerModel ComplexProperty { get; set; } = null!;

    public class InnerModel
    {
        [Display(Name = nameof(Number))]
        [Range(5, 10, ErrorMessage = "The field {0} must be between {1} and {2}.")]
        public int Number { get; set; }
    }
}

app.UseEndpoints(endpoints =>
{
    endpoints
        .MapPost(
            "/api/test",
            static async Task<Results<Ok, ValidationProblem>> (
                [FromBody, Display(Name = nameof(input)), Required] CustomModel input,
                [FromQuery, Display(Name = nameof(someNumber)), Range(1, 100, ErrorMessage = "The argument {0} must be between {1} and {2}.")] int someNumber,
                HttpContext httpContext) =>
            {
                // Get validation results from filter if called 'AddEndpointParameterDataAnnotations()'.
                var results = httpContext.GetEndpointParameterDataAnnotationsValidationResults();
            
                input.Text1 = "new string value";
                someNumber = 107;
            
                // Try to revalidate and update validation results.
                var validationProcessSuccess = await httpContext.TryValidateEndpointParametersAsync([
                    new KeyValuePair<string, object?>(nameof(input), input),
                    new KeyValuePair<string, object?>(nameof(someNumber), someNumber),
                ]);
            
                // Gets validation problem details.
                // If is added Minimal-APIs's localization services, will use localized error messages.
                var problemDetails = httpContext.GetEndpointParameterDataAnnotationsProblemDetails();

                if (problemDetails?.Any() is true)
                {
                    return TypedResults.ValidationProblem(problemDetails);
                }

                return TypedResults.Ok();
            }
        )
        // Add parameter data annotations validation filter to endpoint.
        .AddEndpointParameterDataAnnotations()
        // If paramater has validation error, will return validation problem automatically.
        .AddValidationProblemResult();
}

Main Types

The main types provided by this library are:

  • CoreDX.Extensions.AspNetCore.Mvc.ModelBinding.AsyncParamterBinder
  • CoreDX.Extensions.AspNetCore.Mvc.ModelBinding.Validation.IAsyncObjectModelValidator
  • CoreDX.Extensions.AspNetCore.Http.Validation.Localization.AttributeAdapterBase<TAttribute>
  • CoreDX.Extensions.Validation
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.3.5 74 12/23/2024
1.3.4 74 12/19/2024
1.3.3 91 12/15/2024
1.3.2 72 12/15/2024
1.3.1 84 12/15/2024
1.3.0 87 12/13/2024
1.2.3 88 12/3/2024
1.2.2 90 11/29/2024
1.2.1 91 11/27/2024
1.2.0 102 11/26/2024 1.2.0 is deprecated.
1.1.1 102 11/26/2024 1.1.1 is deprecated because it has critical bugs.
1.1.0 95 11/26/2024
1.0.0 97 11/22/2024

update: Add verifiability check for binding parameter on validation filter.
     update: add NullabilityInfo support for binding parameter on validation filter.