Git Product home page Git Product logo

sharpgrip / fluentvalidation.autovalidation Goto Github PK

View Code? Open in Web Editor NEW
72.0 2.0 7.0 103 KB

SharpGrip FluentValidation AutoValidation is an extension of the FluentValidation library enabling automatic asynchronous validation in MVC controllers and minimal APIs (endpoints).

Home Page: https://sharpgrip.net

License: MIT License

C# 100.00%
csharp fluentvalidation sharpgrip validation async-validation dotnet

fluentvalidation.autovalidation's People

Contributors

alshuriga avatar jonadamsfromnc avatar mgernand avatar mvdgun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fluentvalidation.autovalidation's Issues

Simplifying TypeExtensions.cs IsCustomType method

Hi, I think the code in TypeExtensions.cs

public static bool IsCustomType(this Type? type)
{
    var builtInTypes = new[]
    {
            typeof(string),
            typeof(decimal),
            typeof(DateTime),
            typeof(DateTimeOffset),
            typeof(TimeSpan),
            typeof(Guid)
    };

    return type != null && type.IsClass && !type.IsEnum && !type.IsValueType && !type.IsPrimitive && !builtInTypes.Contains(type);
}

can be simplified by changing the method to:

public static bool IsCustomType(this Type? type)
{
    return type != null && type.IsClass
        && !type.IsEnum && !type.IsValueType
        && !type.IsPrimitive && type != typeof(string);
}

you can check it just with unit-test below (i was using NUnit):

[TestCase(typeof(DateTime))]
[TestCase(typeof(DateTimeOffset))]
[TestCase(typeof(TimeSpan))]
[TestCase(typeof(Guid))]
[TestCase(typeof(decimal))]
[TestCase(typeof(string))]
[TestCase(null)]
public void TypeIsCustom(Type? type)
{
    Assert.IsFalse(
        type != null && type.IsClass 
        && !type.IsEnum && !type.IsValueType 
        && !type.IsPrimitive && type != typeof(string));
}

image

Net8 FluentAutovalidation and the default ModelStateInvalidFilter

LS,
I have a Net 8 api project with an ApiController with the following method

[HttpGet("{companyName}/{groupName}")]

public async Task<IActionResult> GetData([FromRoute] string companyName, [FromRoute] string groupName)

I have FluentValidationAutoValidation configured just as the example in the ReadMe, so with

// Disable the built-in .NET model (data annotations) validation.
configuration.DisableBuiltInModelValidation = true;

// Only validate controllers decorated with the FluentValidationAutoValidation attribute.
configuration.ValidationStrategy = ValidationStrategy.Annotations;

The ApiControler has not been decorated with the [FluentValidationAutoValidation] attribute.

When calling the api, I get a 400 error. In the logging I see:

...
Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder: Debug: Done attempting to validate the bound parameter 'companyName' of type 'System.String'.
...
Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder: Debug: Done attempting to validate the bound parameter 'groupName' of type 'System.String'.
...
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Action Filter: Before executing OnActionExecuting on filter Microsoft.AspNetCore.Mvc.ModelBinding.UnsupportedContentTypeFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Action Filter: After executing OnActionExecuting on filter Microsoft.AspNetCore.Mvc.ModelBinding.UnsupportedContentTypeFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Action Filter: Before executing OnActionExecutionAsync on filter SharpGrip.FluentValidation.AutoValidation.Mvc.Filters.FluentValidationAutoValidationActionFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Action Filter: Before executing OnActionExecuting on filter Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter: Debug: The request has model state errors, returning an error response.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Action Filter: After executing OnActionExecuting on filter Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Debug: Request was short circuited at action filter 'Microsoft.AspNetCore.Mvc.Infrastructure.ModelStateInvalidFilter'.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Action Filter: After executing OnActionExecutionAsync on filter SharpGrip.FluentValidation.AutoValidation.Mvc.Filters.FluentValidationAutoValidationActionFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Action Filter: Before executing OnActionExecuted on filter Microsoft.AspNetCore.Mvc.ModelBinding.UnsupportedContentTypeFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Action Filter: After executing OnActionExecuted on filter Microsoft.AspNetCore.Mvc.ModelBinding.UnsupportedContentTypeFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Result Filter: Before executing OnResultExecuting on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Result Filter: After executing OnResultExecuting on filter Microsoft.AspNetCore.Mvc.Infrastructure.ClientErrorResultFilter.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Result Filter: Before executing OnResultExecuting on filter Microsoft.AspNetCore.Mvc.ProducesAttribute.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Result Filter: After executing OnResultExecuting on filter Microsoft.AspNetCore.Mvc.ProducesAttribute.
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Trace: Before executing action result Microsoft.AspNetCore.Mvc.BadRequestObjectResult.

So somehow the default MVC ModelStateInvalidFilter now determines that the model is invalid.
If I set DisableBuiltInModelValidation to false, this behavior disappears.

Any ideas?

Thanks,
David.

Is it possible to control the schema response in ASP.NET Core?

I would like to set my own response schema in the 400 Bad Request response.

e.g.

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "00-0a4404bdf847cb8cf5f696aac649ee61-5dff3d630c7d9c63-00",
    "errors": {
        "ShownGenderOnProfile": [
            "ShownGenderOnProfile must not be empty"
        ]
    }
}

I am using the auto-validation package SharpGrip.FluentValidation.AutoValidation.Mvc.

Validators not applied to parameters with BindingSource = Form

Hi,

Thanks for providing this package for auto FluentValidation!

My first attempt as using this was trying to apply a Validator to a Form parameter but I see the code specifically only applies validators to Body or Query parameters. Not being a web developer particularly, is there a specific reason for this restriction?

More a question in education (for me) perhaps?

Steve.

add FluentValidationAutoValidationActionFilter BindingSource.Path

Hi. I would like to use your extension for my application but for one of my end endpoint (PUT with id from route) and data from the body payload the validator is not being invoked.

[HttpPut]
[Route("/mymodule/{identifier}")]
public override async Task<ActionResult> HandleAsync([FromRoute] UpdateMyModuleCommand request, CancellationToken cancellationToken = default)

public class UpdateMyModuleCommand
{
[FromRoute(Name = "identifier")] public string Identifier { get; set; }
[FromBody] public UpdateMyModuleCommandParams Params { get; set; }

    public class UpdateMyModuleCommandParams
    {
        public string Name { get; set; }
        .... etc
     }

if in the OnActionExecutionAsync of the FluentValidationAutoValidationActionFilter,
I add this condition then my validator is invoked properly.

Could you please add a confguration EnableRouteBindingSourceAutomaticValidation with the BindingSource.Path in the next version.
Thanks.

if (subject != null && parameterType.IsCustomType() &&
((autoValidationMvcConfiguration.EnableBodyBindingSourceAutomaticValidation && bindingSource == BindingSource.Body) ||
(autoValidationMvcConfiguration.EnableFormBindingSourceAutomaticValidation && bindingSource == BindingSource.Form) ||
(autoValidationMvcConfiguration.EnableQueryBindingSourceAutomaticValidation && bindingSource == BindingSource.Query) ||
(autoValidationMvcConfiguration.EnableCustomBindingSourceAutomaticValidation && bindingSource == BindingSource.Custom) ||
(bindingSource == BindingSource.Path)
)
)
{

Improve MVC endpoint detection

Hi, I've decided to try out your package due to older one from FluentValidation being deprecated. But I've bumped into a issue where none of my validators were actually fired. I've debugged everything and noted that the IAsyncFilter that you use to wire things up is detecting the MVC endpoints based of if controller is actually ControllerBase.

My current project is using a bit of a different MVC setup where controllers are not inherited but make use of ApiController attribute and conventions as described here.

Due to that validators won't get triggered as controllers are convention based and do not inherit ControllerBase or other controller based classes that are provided out of the box.

It would be great if we can somehow support this so that this flavor of MVC controllers will trigger validators automatically also.

PS: thanks for awesome project.

ICollection<T> support

Current implementation checks if parameter type is class. This check fails if we use ICollection<T> as parameter type.
ASP.NET is able to deserialize to it, it is also possible to create and register IValidator<ICollection<T>>.

What is the reason for not allowing such interfaces to be auto-validated?

In PR with refactor of IsCustomType (#32) it is proposed to change to even more strict, by disallowing anything that implements IEnumerable, which I would consider breaking change and would like to understand the reason for it.

Auto validation with custom model binder

Hi,

I am trying to use auto request validation in an app that uses a custom model binder.
Looking at the code here , I see the accepted binding sources are Query, Form and Body. Would it be possible to extend that to allow custom binding sources as well?

Thank you!

Multiple binding sources are not supported

Hi!
When binding attributes are defined in class and this class is used in action as a parameter then library is not triggering validation because BindingSource is null.

builder.Services.AddFluentValidationAutoValidation(configuration =>
{
    configuration.DisableBuiltInModelValidation = false;
    configuration.ValidationStrategy = ValidationStrategy.All;
    configuration.EnableBodyBindingSourceAutomaticValidation = true;
    configuration.EnableFormBindingSourceAutomaticValidation = true;
    configuration.EnableQueryBindingSourceAutomaticValidation = true;
    configuration.EnablePathBindingSourceAutomaticValidation = true;
    configuration.EnableCustomBindingSourceAutomaticValidation = true;
});

//register Validators
builder.Services.AddValidatorsFromAssembly(
    Assembly.GetExecutingAssembly());



[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    // GET api/<ValuesController>/5?val1=1&val2=aaa
    [HttpGet("{id}")]
    public string Get(GetByIdRequest request)
    {
        return "value";
    }
}

public record GetByIdRequest
{
    [FromRoute(Name = "id")]
    public int Id { get; set; }

    [FromQuery(Name = "val1")]
    public int Val1 { get; set; }

    [FromQuery(Name = "val2")]
    public string Val2 { get; set; }
}

public class GetByIdRequestValidator : AbstractValidator<GetByIdRequest>
{
    public GetByIdRequestValidator()
    {
        RuleFor(n => n.Val1).InclusiveBetween(5,10);
        RuleFor(n => n.Val2).NotEmpty();
    }
}

Disabling validation of parameters with [NeverValidate]

It would be great if we could disable validation on specific parameters with the existing [NeverValidate] attribute.
Expected behavior from the existing model validation is to:

  1. Ignore any classes marked with this attribute
  2. Ignore any parameters marked with this attribute

I took a look in the action filter but it appears to be quite difficult to get the attributes of the parameter.

I'd be happy to take a look and implement if there is any interest in this.

Improve/extend context in the IFluentValidationAutoValidationResultFactory

hi,
i'm using rules with ErrorCode and ErrorMessage, example:

RuleFor(request => request.FirstName).NotNull()
  .WithErrorCode(errorCode)
  .WithMessage(errorMessage);

i would like that my validation has ErrorCode and errorMessage

I'm using CustomResultFactory, find below my configuration, but i'm not able to find the object that contains errors with code and messagge (the same object that i find when i use manual validation)

FluentValidation.Results.ValidationFailure

public class CustomResultFactory : IFluentValidationAutoValidationResultFactory
{
    public IActionResult CreateActionResult(ActionExecutingContext context, ValidationProblemDetails? validationProblemDetails)
    {
       return new BadRequestObjectResult(new { Title = "Validation errors", ValidationErrors = validationProblemDetails?.Errors });
    }
}

services.AddFluentValidationAutoValidation(configuration =>
{
    // Disable the built-in .NET model (data annotations) validation.
    configuration.DisableBuiltInModelValidation = true;
     
    // Only validate controllers decorated with the `FluentValidationAutoValidation` attribute.
    configuration.ValidationStrategy = ValidationStrategy.All;

    // Enable validation for parameters bound from the `BindingSource.Body` binding source.
    configuration.EnableBodyBindingSourceAutomaticValidation = true;

    // Enable validation for parameters bound from the `BindingSource.Form` binding source.
    configuration.EnableFormBindingSourceAutomaticValidation = true;

    // Enable validation for parameters bound from the `BindingSource.Query` binding source.
    configuration.EnableQueryBindingSourceAutomaticValidation = true;

    // Replace the default result factory with a custom implementation.
    configuration.OverrideDefaultResultFactoryWith<CustomResultFactory>();
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.