Code Monkey home page Code Monkey logo

fluentvalidation's Introduction

FluentValidation

Build Status NuGet Nuget

Full Documentation

A validation library for .NET that uses a fluent interface and lambda expressions for building strongly-typed validation rules.


Supporting the project

If you use FluentValidation in a commercial project, please sponsor the project financially. FluentValidation is developed and supported by @JeremySkinner for free in his spare time and financial sponsorship helps keep the project going. You can sponsor the project via either GitHub sponsors or OpenCollective.


Get Started

FluentValidation can be installed using the Nuget package manager or the dotnet CLI.

dotnet add package FluentValidation

Review our documentation for instructions on how to use the package.


Example

using FluentValidation;

public class CustomerValidator: AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(x => x.Surname).NotEmpty();
    RuleFor(x => x.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(x => x.Discount).NotEqual(0).When(x => x.HasDiscount);
    RuleFor(x => x.Address).Length(20, 250);
    RuleFor(x => x.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

var customer = new Customer();
var validator = new CustomerValidator();

// Execute the validator
ValidationResult results = validator.Validate(customer);

// Inspect any validation failures.
bool success = results.IsValid;
List<ValidationFailure> failures = results.Errors;

License, Copyright etc

FluentValidation has adopted the Code of Conduct defined by the Contributor Covenant to clarify expected behavior in our community. For more information see the .NET Foundation Code of Conduct.

FluentValidation is copyright © 2008-2022 .NET Foundation, Jeremy Skinner and other contributors and is licensed under the Apache2 license.

Sponsors

This project is sponsored by the following organisations whose support help keep this project going:

  • Microsoft for their financial contribution
  • JetBrains for providing licenses to their developer tools

This project is part of the .NET Foundation.

fluentvalidation's People

Contributors

abatishchev avatar ademcatamak avatar arphox avatar avrahamcool avatar batzen avatar chris-za avatar ddyakov avatar dmorganb avatar filipkristo avatar happtim avatar janv8000 avatar jeremymeng avatar jeremyskinner avatar leehom0123 avatar maksimkim avatar matteobaglini avatar mattleibow avatar medvedbeast avatar mourisso avatar nsarris avatar proffrugal avatar purekrome avatar ragnarstolsmark avatar richardlawley avatar robert-mccausland avatar seankilleen avatar simoncropp avatar utsxumiao avatar vetranio avatar wizofaus 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  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  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  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

fluentvalidation's Issues

Stop future validation rules if a rule fails

Feature Request:

Given this definition

public class MyInsideItem {
      public string InsideProp {get;set;}
}

public class MyItem {
    public MyInsideItem Item {get;set;}      
}

The validator today would have to be written like this:

    public class MyItemValidator : AbstractValidator<MyItem>
    {
        public MyItemValidator()
        {
                RuleFor(x => x.MyInsideItem).NotNull();
                When(x => x.MyInsideItem != null, () =>
                {
                    RuleFor(x => x.MyInsideItem.InsideProp).NotEmpty(0);
                });
        }
    }

As you can see, the null check is really done twice and we already know it does not need to go on. In this case it is a simple null check - but the validation to decide on if I should validate the internal property could be complex.

Proposal would be:

    1. Something to stop future rules all together
    public class MyItemValidator : AbstractValidator<MyItem>
    {
        public MyItemValidator()
        {
                RuleFor(x => x.MyInsideItem).NotNull().StopValidatingOnFailure();
                RuleFor(x => x.MyInsideItem.InsideProp).NotEmpty(0);
        }
    }

    1. Dependency rules
    public class MyItemValidator : AbstractValidator<MyItem>
    {
        public MyItemValidator()
        {
                RuleFor(x => x.MyInsideItem).NotNull().WhenValid( ()=> 
                {
                    RuleFor(x => x.MyInsideItem.InsideProp).NotEmpty(0);
                }
        }
    }

Given how everything works with fluent, I think # 2 (Dependency rule) implementation above would be the easiest, because it is a lot like a when and should be an easy adaptation. # 1 (stop all future rules) has the possibly negative effect of stopping ALL future rules from executing and you may want some rules to fire, just not the dependent rules - so the dependency rules version is better in that regard too.

This is not a new feature request, but perhaps a new way to easily implement it? See
http://fluentvalidation.codeplex.com/discussions/352581

rule and ruleset list

It would be nice to have the validator output a list of rules and rule lists. Is this already possible?

string jsonRules = validator.GetRulesJson(); // or...
List<ValidationRule> rules = validator.GetRulesList(); 
// and
validator.GetRules( "ruleset1" ); // or...
validator.GetValidatedProperties()....

How to specify ErrorCode

Can someone please tell me how to specify the ErrorCode property of the ValidationFailure instance?
I see code examples where .WithErrorCode("SomeErrorCode") is used (similar to WithMessage() and WithState()). However, is seems the WithErrorCode() is not defined in the DefaultValidatorOptions class.

how inject or find validators by entity type?

hello
how inject or find validators by entity type?
i have following classes:
public class BaseEntity {}

public class Article :BaseEntity
{
public string Name {get;set;}
}

public class ArticleValidator : AbstractValidator


{
public ArticleValidator()
{
RuleFor(x => x.Name ).NotEmpty().Length(0,512);
}

}

and have extentions for BaseEntity:
public static ValidationResult Validate(this BaseEntity entity)
{
????//and here how i can find entity validator by type of entity and validate it and return result.

}

public class ArticleService
{
public void AddArticle(Article aricle)
{
var result = article.Validate();
if(result.IsValid)
.......
.......
}
}

Strong Naming

Hi,

Would it be possible for you to strong name your assemblies? I want to use some of your NuGet packages, and I'm running into issues because my assemblies must be strong named.

Thanks.

Extending ValidationContext doesn't work as expected

We have a scenario where we want to be able to pass a custom data access object (IUnitOfWork) as a part of the ValidationContext so that we can perform dynamic validation against our database.

The custom object will be a different instance every time that we perform validation and call the validator using the following:

Initially we extended ValidationContext to add the custom object as a property that we could retrieve in other validators.

await validator.ValidateAsync(new ValidationContextWithUnitOfWork(instanceToValidate, unitOfWork);

So in a property validator we could do this:

class CustomPropertyValidator : PropertyValidator
{
    ...
    bool IsValid(PropertyValidatorContext context)
    {
        var unitOfWork = (context.Parent as ValidationContextWithUnitOfWork).UnitOfWork;
    }
}

The problem is that the custom ValidationContext is not passed to the child validator instead it is always an instance of ValidationContext.

This appears to be because the Clone method of the ValidationContext base class only ever returns a ValidationContext.

https://github.com/mattleibow/FluentValidation/blob/master/src/FluentValidation/ValidationContext.cs#L54

We would like to make this method virtual so that we can override it to always produce the correct instance.

Is this possible? Are we even on the right track here?

Another possible solution is to use a container to resolve a new validator for each call and inject the IUnitOfWork instance into the constructor. However this seems to be a odds with the way FluentValidation works and presumably will somewhat slower.

Using Fluent Validation 5.5 with angular

Hello,

We're trying to reuse the validation rules we have defined on the server in an MVC 5 application on the client side using Angular. If possible, we would like to avoid duplicating the validation rules defined in our Validator classes.

Ex.
We have this rule on the server
RuleFor(x => x.LastName).Length(0, 41);

How can we generate client script validation that will prevent excessive characters on the last name textbox?

Our objectives are to
Define validation rules in one place
Validate data on the client without contacting the server.

Any ideas?

ShouldHaveChildValidator should pass in conditional validation statements

ShouldHaveChildValidator should pass in conditional validation statements or a new function should be created for if a child validator is declared conditionally

Example Code Below:

using System.Collections.Generic;
using FluentValidation;
using BDBPayroll.Apps.API.Services.Tests.Shared;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using FluentValidation.TestHelper;

namespace BDBPayroll.Apps.API.Services.Tests
{
    [TestClass()]
    public class TestChildValidator : ServiceTestBase
    {
        [TestMethod]
        public void Conditional_child_Validator_Pass_Test()
        {
            var passValidator = new TestPassValidator();
            passValidator.ShouldHaveChildValidator(x => x.SomeCrap, typeof(ChildValidator));
        }

        [TestMethod]
        public void Conditional_child_Validator_Fail_Test()
        {
            var failValidator = new TestFailValidator();
            failValidator.ShouldHaveChildValidator(x => x.SomeCrap, typeof(ChildValidator));
        }
    }

    public class TestFailValidator : AbstractValidator<TestObj>
    {
        public TestFailValidator()
        {
            this.Unless(x => true, this.SetValidationRules);                
        }

        public void SetValidationRules()
        {
            this.RuleFor(i => i.SomeCrap).SetCollectionValidator(new ChildValidator());
        }
    }

    public class TestPassValidator : AbstractValidator<TestObj>
    {
        public TestPassValidator()
        {
            this.RuleFor(i => i.SomeCrap).SetCollectionValidator(new ChildValidator());
        }
    } 

    public class ChildValidator : AbstractValidator<TestChildObj>
    {

    }

    public class TestObj
    {
        public List<TestChildObj> SomeCrap;
    }

    public class TestChildObj
    {
    }

}

ValidatorFactory.CreateInstane Called Numerous Times

This stackoverflow question describe's what is going on except I am using StructureMap.

I am adding my custom Factory like

      FluentValidationModelValidatorProvider.Configure(provider =>
       {
           provider.ValidatorFactory = new StructureMapValidatorFactory(container);
       });

The Create Instance method of the factory is called once for each ViewModel property on the "Get" method.

When I form post, with no properties on the view, It is called 5 times.

Otherwise it is called (5 + (2 * numberOfProperties)).

I'm not sure if this is a bug or working as intended within the MVC architecture.

I would expect CreateInstance to be called only once on form post, maybe on Get.

For the sake of completeness here is my factory class

 public class StructureMapValidatorFactory : ValidatorFactoryBase
    {
        private readonly IContainer container;

        public StructureMapValidatorFactory(IContainer container)
        {
            this.container = container;
        }

        public override IValidator CreateInstance(Type validatorType)
        {
           return container.TryGetInstance(validatorType) as IValidator;
        }
    }

Help with customizing extensions for .WithName()

Looking to do something similar to what is described here, but with Name rather than Message
http://fluentvalidation.codeplex.com/discussions/440136

Does it make sense to modify PropertyRule to have another property similar to how MessageBuilder works. That would allow me to do something like:

RuleFor(x => x.City)
.NotEmpty()
.WithName(x => x.DisplayPrefix + " City");

That way I could have 2 models of the same type generate different error messages in the same validation context.

Departure City should not be empty
Arrival City should not be empty

A simplified model would look something like this:

public class SearchModel
{
public SearchLocationModel DepartureLocation {get;set;}
public SearchLocationModel ArrivalLocation {get;set;}
}

public class SearchLocationModel
{
public string DisplayPrefix {get;set;}
public string City {get;set;}
}

Or perhaps there is a better way to accomplish this?

Best validator design?

Hi there.

Im having design issues related to making a standardized way of using fluent validation in my development team. Let me try and explain my problem:

1, In my team we will be making over 100 different validators
2. I want it to be easy for new team members to start coding validators. At the same time I want the validator design to be consistent so I have defined a base class which every validator must inherit from. This way I can keep my concrete validators very small (and DRY) as the only code needed is the validation rule definition code.
3. I would prefer to keep all rule definitions in the constructors of my validators to separate rule definition and rule execution and make sure that the rule definition are only added once. Sometimes I need to perform custom validation on some data which is not available to me before I execute the validation. Therefore I currently dont have my rule definition in my constructor, but in a method defined as abstract on my base validator. It smells, but it works. I think there may be a better way of doing this, hence this question.

Any help appreciated.

public abstract class ValidatorBase : AbstractValidator
{
public abstract void InitValidationRules();
protected T ItemToValidate;

public void Validate(T itemToValidate)
{
ItemToValidate = itemToValidate;
InitValidationRules();
var result = Validate(itemToValidate);
...
}

public class CustomerValidator : ValidatorBase
{
public override void InitValidationRules()
{
//problem here is that my custom validator expects a concrete value rather than a lambda
RuleFor(x => ItemToValidate.Aktuelle).MustNotContain(ItemToValidate.Opret.Kred).
}
}

public static class FluentValidationExtensions
{

    public static IRuleBuilderOptions<T, IList<TElement>> MustNotContain<T, TElement>(this IRuleBuilder<T, IList<TElement>> ruleBuilder, TElement value)
{
  return ruleBuilder.SetValidator(new MustNotContain<TElement>(value));
}

}

public class MustNotContain : PropertyValidator
{
private readonly T _value;

public MustNotContain(T value)
        : base(string.Format("Value {0} for {{PropertyName}} is illegal, as it exists!",value))
{
  _value = value;
}

protected override bool IsValid(PropertyValidatorContext context)
{
    var list = context.PropertyValue as IList<T>;
    return (list == null || !list.Contains(_value));
}

}

Model rules

I think it may be useful to have the concept of rules that apply to the entire model in addition to property-based rules. Model rules would only run after the property rules have all passed.

An example is a simple sign-in model with Email Address and Password. What I'd like to write is:

this.RuleFor(m => m.EmailAddress).NotEmpty().EmailAddress();
this.RuleFor(m => m.Password).NotEmpty();
this.RuleForModel(this.ValidatePasswordInDatabase).WithMessage("Email or password is invalid.");

private bool this.ValidatePasswordInDatabase(SignInModel model)
{
     // expensive operation here when an email and password are present
}

As far as I can tell, this is impossible with the current system without doing hacks with .When and essentially re-validating properties.

I'd be happy to work on a pull request if there's support for the idea.

Testing complex object

Hi,

I have below set up.

Class Person{
public Address HomeAddress {get;set;}
}

How do i test if homeaddress null or not?

public class PersonValidator : AbstractValidator {
RuleFor(e => e.HomeAddress).NotNull().WithMessage("Home Address cannot be null");
}

//Below does not work
_validator.ShouldHaveValidationErrorFor(p => p.HomeAddress, null as HomeAddress);

MVC 5 Dropdown using NHibernate and FluentValidation

Dear All;

I am newbie at MVC 5. I am using Nhibernate, FluentValidation and MVC 5.
I have a problem with validation. I think maybe this group users know solution.

I want to use Complex Object type. I binded Site Property a dropdown Page model. I loaded Page form and post data. My model Site property has ID (ValueMember) value and Domain (DisplayMember) value. This is no problem I am using Nhibernate Merge method for save. FluentValidation Validate Site property and ModelState.IsValid is false. Because My Site Validator has RuleFor(x=>x.Title).NotEmpty(). ModelState Errors has this rule error.

How can i solve this problem or How can i use DropDown for Relational Model?

Best Regards.

Models

[Validator(typeof(PageValidator))]
    public class Page : Persist<Page>
    {
        [Key]
        public virtual long ID { get; set; }
        public virtual Site Site { get; set; }
        public virtual Page Parent { get; set; }
        public virtual string Title { get; set; }
        public virtual string Slug { get; set; }
...
..
..
}


[Validator(typeof(SiteValidator))]
    public class Site : Persist<Site> , IHasDefaultValue
    {
        [Key]
        public virtual long ID { get; set; }
        public virtual string Title { get; set; }
        public virtual string Description { get; set; }
        public virtual string Keywords { get; set; }
        public virtual string Domain { get; set; }
...
...
...
..
}

View

            <div class="form-group">
                @Html.LabelFor(x => x.Site, new {@class = "col-sm-3 control-label"})
                <div class="col-sm-6">
                    @Html.DropDownListFor(x => x.Site.ID,
                    new SelectList(Site.List(), "ID", "Domain")
                    , new { @class = "form-control" })
                    @Html.ValidationMessageFor(x => x.Site, null, new {@class = "help-inline error"})
                </div>
            </div>

Controller

[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(Page model, string command)
        {
            if (ModelState.IsValid) /// this always false because Site property has only ID and Domain property value. Validators Validate Site property
            {
                try
                {
                    BeforeCreate(model);
                    model.Save();
                    AfterCreate(model);
                    if (command=="SaveAndStay")
                    {
                        return RedirectToAction("Update", new { id = model.GetId() });    
                    }
                    else if (command == "SaveAndNew")
                    {
                        return RedirectToAction("Create");
                    }
                    else
                    {
                        return RedirectToAction("Index");
                    }
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", ex.Message);
                }
            }
            return View("Create", model);
        }

Validators

public class SiteValidator : AbstractValidator<Site>
    {
        public SiteValidator()
        {
            RuleFor(x => x.Title).NotEmpty().WithMessage("Lütfen siteniz için bir başlık belirleyiniz.");
            RuleFor(x => x.Domain).NotEmpty().WithMessage("Lütfen sitenizin alan adını giriniz.");
            RuleFor(x => x.Locale).NotEmpty().WithMessage("Lütfen sitenizin dilini seçiniz.");
            When(x => !string.IsNullOrEmpty(x.Domain), () =>
            {
                RuleFor(x => x.Domain)
                    .Must(UniqueDomain)
                    .WithMessage("{0} alan adına sahip bi site zaten tanımlı.", x => x.Domain);
            });
        }

        private bool UniqueDomain(Site instance, string domain)
        {
            return !Site.IsExists(x => x.Domain == domain && x.ID != instance.ID);
        }
    }

public class PageValidator : AbstractValidator<Page>
    {
        public PageValidator()
        {
            RuleFor(x => x.Site).NotNull().WithMessage("Lütfen sayfanın yayınlanacağı siteyi seçiniz.");
            RuleFor(x => x.Title).NotEmpty().WithMessage("Lütfen bir başlık belirleyiniz");
            RuleFor(x => x.Slug).NotEmpty().WithMessage("Link bilgisi alınamadı");

        }
    }

Propagate child errors with parent context

Similar problems:
1 https://fluentvalidation.codeplex.com/discussions/355838
2 http://stackoverflow.com/questions/14490671/propagate-child-errors-to-parent-in-fluentvalidation
3 https://fluentvalidation.codeplex.com/discussions/355996

We has no parent context when validating child collection. The error message contains information about property of child entity, but not about parent.
I propose

class Parent{
    public Parent() {
        Childs = new List<Child>();
    }
    public string Name { get; set; }
    public IList<Child> Childs { get; set; }
}
class Child{
    public string Value { get; set; }
}

class  ParentValidator: AbstractValidator<Parent> {
    public ParentValidator() {
        RuleFor(p => p.Childs).SetCollectionValidator(new ChildValidator())
            .WithParentMessage("Error in '{0}' with message '[ChildMessage]'", p => p.Name);
    }
}
class ChildValidator : AbstractValidator<Child>{
    public ChildValidator() {
        RuleFor(c => c.Value).NotEmpty();
    }
}

I modified some classes in FluentValidation and this code is work, but my solution is quick and not tested

Installing through NuGet on VS2013 For Web

Hello

Installing Fluent Validation in Visual Studio Express 2013 for Web is failing. Not sure what exactly is wrong. Below is the output from the NuGet Console.

I've attempted to install older versions of the FV package but the same error occurs. I've installed on blank ASP .NET MVC projects to ensure that my other packages are not conflicting and the same error occurs.

Any ideas whats wrong?

NuGet Command: Install-Package FluentValidation

PM> Install-Package FluentValidation
Installing 'FluentValidation 5.6.2.0'.
Successfully installed 'FluentValidation 5.6.2.0'.
Adding 'FluentValidation 5.6.2.0' to Server.
Uninstalling 'FluentValidation 5.6.2.0'.
Successfully uninstalled 'FluentValidation 5.6.2.0'.
Install failed. Rolling back...
Install-Package : Specified argument was out of the range of valid values.
Parameter name: supportedFrameworks
At line:1 char:1

  • Install-Package FluentValidation
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], ArgumentOutOfRangeException  
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PowerShell.Commands.InstallPackageCommand  
    

NuGet Command: Install-Package FluentValidation.MVC5

PM> Install-Package FluentValidation.MVC5
Attempting to resolve dependency 'FluentValidation (≥ 5.6.2.0)'.
Attempting to resolve dependency 'Microsoft.AspNet.Mvc (≥ 5.1 && < 5.3)'.
Attempting to resolve dependency 'Microsoft.AspNet.WebPages (≥ 3.1.0 && < 3.2.0)'.
Attempting to resolve dependency 'Microsoft.Web.Infrastructure (≥ 1.0.0.0)'.
Attempting to resolve dependency 'Microsoft.AspNet.Razor (≥ 3.1.0 && < 3.2.0)'.
Installing 'FluentValidation 5.6.2.0'.
Successfully installed 'FluentValidation 5.6.2.0'.
Installing 'Microsoft.Web.Infrastructure 1.0.0.0'.
Successfully installed 'Microsoft.Web.Infrastructure 1.0.0.0'.
Installing 'Microsoft.AspNet.Razor 3.1.0'.
You are downloading Microsoft.AspNet.Razor from Microsoft, the license agreement to which is available at http://aspnetwebstack.codeplex.com/license. Check the package for additional dependencies, which may come with their own license agreement(s). Your use of the package and dependencies constitutes your acceptance of their license agreements. If you do not accept the license agreement(s), then delete the relevant components from your device.
Successfully installed 'Microsoft.AspNet.Razor 3.1.0'.
Installing 'Microsoft.AspNet.WebPages 3.1.0'.
You are downloading Microsoft.AspNet.WebPages from Microsoft, the license agreement to which is available at http://aspnetwebstack.codeplex.com/license. Check the package for additional dependencies, which may come with their own license agreement(s). Your use of the package and dependencies constitutes your acceptance of their license agreements. If you do not accept the license agreement(s), then delete the relevant components from your device.
Successfully installed 'Microsoft.AspNet.WebPages 3.1.0'.
Installing 'Microsoft.AspNet.Mvc 5.1.0'.
You are downloading Microsoft.AspNet.Mvc from Microsoft, the license agreement to which is available at http://aspnetwebstack.codeplex.com/license. Check the package for additional dependencies, which may come with their own license agreement(s). Your use of the package and dependencies constitutes your acceptance of their license agreements. If you do not accept the license agreement(s), then delete the relevant components from your device.
Successfully installed 'Microsoft.AspNet.Mvc 5.1.0'.
Installing 'FluentValidation.MVC5 5.6.2.0'.
Successfully installed 'FluentValidation.MVC5 5.6.2.0'.
Install failed. Rolling back...
Install-Package : Already referencing a newer version of 'Microsoft.AspNet.Razor'.
At line:1 char:1

  • Install-Package FluentValidation.MVC5
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], InvalidOperationException  
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PowerShell.Commands.InstallPackageCommand  
    

SetValidator does not correctly set the display name if the field getting validated is a string and not a complex type

On our API we sometimes need to set validators off fields that are not complex types i.e. strings.
For example, we have a validator to handle passwords which is re-used in a couple of handlers.

Nested validator 
public class PasswordValidator : AbstractValidator<string>
{
    public PasswordValidator()
    {
        RuleFor(x => x).NotEmpty().Length(8, 100);
        RuleFor(x => x).Must(
            (key, p) => --> more complex rules here <--);
    }
 }

In our validators 
RuleFor(x => x.TransferObject.Password).SetValidator(new PasswordValidator())

The validation works but the error message is wrong. Instead of the message starting with 'Password' it starts with '' i.e. no field name set. The property name is set correctly.

If you try to use the WithName in the PasswordValidator then this fixes the error message but now the property name is incorrect. So in the above example the property name would become ''TransferObject.Password.Password" instead of "TransferObject.Password"

I have submitted a pull request that adds 2 failing tests that show the issue. #88

Get the validated viewmodel inside the validator

Hi,
how can I get the validated viewmodel inside the validator:

public class SomeValidator : AbstractValidator
{

public SomeValidator()
{

var itemToBeValidated = ???? (how do I get the objected represented by the "item" in the expression)

RuleFor(item => item.Name).Must(NotBeEmpty);

}

}

Ability to set rules on collection elements.

It would be nice to be able to recursively add rules on collection item properties.

      RuleForEach(s => s.Administrators)
        .RuleFor(c => c.Username, 
          r => r.NotEmpty()
                .EmailAddress());       

Multiple Range Validation

Hi There.

Context : My current assignment is purely based on c# where I need to read some data from flat files,convert the data into objects of classes and validate these objects before I insert them into database.

My problem : I need to validate the objects. Validations include, DataType check,IsNull,Required, Range and property value based on some other property value(Ex : prop1 should have value as y if prop2 has value as x :: IF ITEM 67 = 2,3,5 ITEM 75 MUST = 01-16,98,99 (read Item as property)
) . Also by range validation I mean, prop 1 can either lie in range1(say 40-50) or range 2(70-90). I have been doing this by writing a separate method for each property validation as I need to log the exceptions/validation results into the database. This is causing me to write 1000's of lines of code as I have nearly 176 properties on each object.

While looking for a solution on internet I came across this Fluent validation. I forked the code and had a look at it. I must say this is an outstanding project.I could not find the feature of multiple-range validation in this. ( a property can exist in either range1 or range2 or range 3 or..so on). Could we have this feature set-up in your project?If not,I want to write a simple class library which does this work. can I get some guidance to organize/architecture the code for my problem?

-Hanuma

vNext / MVC 6 Integration

Hi,

i saw you have created a branch for vNext / Mvc6. When do you plan a beta / final release?

Regards

Values that exceed max int do not show validation in ValidationSummary

I found this post on codeplex: https://fluentvalidation.codeplex.com/workitem/7105

I am having the same issue. In the response to this issue there was an example unit test but that doesn't show what the actually problem is. The validation is working. I can see a validation message if I use the Html.ValidationMessageFor method. I will get something like "The value '99999999999999999999999' is invalid."

The problem is I have Html.ValidationSummary at the top of the form and it is empty. The form does not save the data because validation fails (which is good), but my validation summary shows an empty red box instead of having the validation message displayed.

Errors deploying to Windows Phone (MDILXapCompileLog error 1004)

When using FluentValidation on Windows 10 with Visual Studio 2015 I get the following error whilst deploying to a Windows Phone 8.1 device:

Error : DEP6810 : MdilXapCompile.exe failed with error code 1004. See log file 'C:\Users\solve\Documents\Projects\...\Project.WindowsPhone\obj\Debug\MDIL\MDILXapCompileLog.txt' for more details.  MobileNinja.WindowsPhone        

The MDILXapCompileLog.txt file mentioned in the error contained the following:

Error: Compile filter argument specified non-existent file: C:\Users\...\Project.WindowsPhone\obj\Debug\MSIL\da\FluentValidation.resources.dll
Invalid argument

Microsoft (R) MDIL XAP Compiler - Version 4.0.0.0
Copyright (c) Microsoft Corporation.  All rights reserved.

Usage: MDILXAPCompile /In:<InputPath> /Out:<OutputPath> /Config:<ConfigPath> [/CompileFilter:<Assembly Path>;<Assembly Path>] [/Timeout:<Timeout>] [/Log:<LogPath>] [/AppX]

/In     - Path to directory containing files to process
/Out        - Path to directory to place processed files in
/Config     - Path to configuration file
/CompileFilter  - Optional restrictive list of assembly files in InputPath,
          separated by semi-colons, to be compiled.
/Timeout    - Optional timeout in milliseconds before killing the Crossgen process. Overrides config file timeout value. Use -1 for infinite timeout, 0 for application default (2 hours).
/Log        - Optional path to log file
/AppX       - Specifies that assemblies correspond to an AppX package

Relative paths are relative to this executable's directory.

I can deploy the application to a Windows Store app and have previously been able to deploy it to a Windows Phone using Windows 8.1 with VS 2013. I am aware that the error might be something about my new set-up but only FluentValidation is causing errors, which seems weird.

Neither FluentValidation 5.6.0 or 5.5.0 seem to work, both reproduce the same error. Also cleaning/rebuilding the solution doesn't help.

Any ideas on this issue?

AssemblyScanner - Release 5.6.0

Not working in the latest release -

var validators = AssemblyScanner.FindValidatorsInAssemblyContaining<ValidatorFactory>();
validators.ForEach(validator => unityContainer.RegisterType(validator.InterfaceType, validator.ValidatorType, new ContainerControlledLifetimeManager()));

Returns nothing found after upgrading to 5.6.0 from 5.5.0. Reverting back to 5.5.0 resolves the issue.

IValidator.ValidateAsync should support passing in a CancellationToken.

If you have a validation that is taking a long time you should have some way of cancelling it.

public interface IValidator {
...
        Task<ValidationResult> ValidateAsync(object instance, CancellationToken cancellation = new CancellationToken());
        Task<ValidationResult> ValidateAsync(ValidationContext context, CancellationToken cancellation = new CancellationToken());
...
    }
    public interface IValidator<in T> : IValidator {
...
        Task<ValidationResult> ValidateAsync(T instance, CancellationToken cancellation = new CancellationToken());
...
    }

FluentValidationModelValidatorProvider.Configure() is not recognized in Application_Start()

It seems that FluentValidation doesn't suport MVC 5.
I have installed the latest package from nuget and have created the validation but when i try to add

FluentValidationModelValidatorProvider.Configure(); under protected void Application_Start() i have the following error message:
The name 'FluentValidationModelValidatorProvider' does not exist in the current context

Anyone knows hat the problem might be?

ObjectGraph not entirely validated with WebAPI

When calling a POST action of a controller with an object that is a complex type with sub types, there is only the root validator for the complex type that is validated. Subproperties are not validated.

The cause seems to be in the file FluentValidationModelValidatorProvider.cs where we get the validators for the property being validated. If we are getting the validators for a property, then a break is yielded and no validator are returned so the validator for my complex type property is not returned.

If I comment the following code in FluentValidationModelValidatorProvider.GetValidators :

if (IsValidatingProperty(metadata))
{
    yield break;
}

Then it is validating all the entire graph as expected.

Here is the code to reproduce this issue :

public class TestController : ApiController
{
    [Route("~/api/create-test")]
    public IHttpActionResult CreateTest(TestRequest testRequest)
    {
        if (!ModelState.IsValid)
        {
            return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
        }

        var testResponse = new TestResponse {TestString = testRequest.TestString};
        return ResponseMessage(Request.CreateResponse(HttpStatusCode.OK, testResponse));
    }

    [Validator(typeof(TestRequestValidator))]
    public class TestRequest
    {
        public string TestString { get; set; }
        public TestSubRequest TestSubRequest { get; set; }
    }

    [Validator(typeof(TestSubRequestValidator))]
    public class TestSubRequest
    {
        public string TestSubString { get; set; }
    }

    public class TestResponse
    {
        public string TestString { get; set; }
    }

    public class TestRequestValidator : AbstractValidator<TestRequest>
    {
        public TestRequestValidator()
        {
            RuleFor(entity => entity.TestString).NotNull().WithMessage("TestString shoud not be null");
        }
    }

    public class TestSubRequestValidator : AbstractValidator<TestSubRequest>
    {
        public TestSubRequestValidator()
        {
            RuleFor(entity => entity.TestSubString).NotNull().WithMessage("TestSubString shoud not be null");
        }
    }
}

Call it with this json object:

    {
        "TestString" : null,
        "TestSubRequest" : {
            "TestSubString" : null
        }
    }

MustAsync makes browser hanging on without resolving

Hello,

I have the following Validator on a MVC5 site:

public class CatalogCreateModelValidator : AbstractValidator<CatalogCreateModel> {

  public CatalogCreateModelValidator(Func<IMediator> mediator) {      
    RuleFor(x => x.Name)
      .NotEmpty().WithMessage("The name is required")
      .MustAsync(name => mediator().SendAsync(new CatalogNameValidationModel(name)))
      .WithMessage("The name is unavailable");
  }
}

When the name is empty I get an error on my view.
When name is not empty the browser hangs on "loading" without showing the error.

It seems it hangs on MustAsync ... The validation of the CatalogNameValidationModel is:

public class CatalogNameValidationModelHandler : IAsyncOrderHandler<CatalogNameValidationModel, Boolean> {

  private readonly IDbContext _context;

  public CatalogNameValidationModelHandler(IDbContext context) {
    _context = context;
  }

public async Task<Boolean> Handle(CatalogNameValidationModel model) {
   return !await _context.Catalogs.AnyAsync(x => x.Name == model.Name);
} // Handle

}

My application works fine with Async in controllers ...

The only think it is not working is the MustAsync validation.

Thank You,
Miguel

Unable to validate Collection length > 0 client side

I am currently leveraging FluentValidation in an MVC 5 application and am experiencing an issue where I'm initializing a NotEmpty validator for a property of type List as follows:

this.RuleFor(x => x.IntList)
      .NotEmpty()
      .WithLocalizedMessage(() => Resources.Errors.Required);

I am not seeing any validation attributes on my element client side and am not getting IsRequired =true in my model metadata for that property. Any guidance would be more than welcome.

How to use CascadeMode.StopOnFirstFailure when mixing RuleFor with Custom

What would be the way to make sure a Custom block doesn't execute? In this case, the validator validates strings.

public EmailValidator()
{
RuleFor(vm => vm).Cascade(CascadeMode.StopOnFirstFailure).NotNull().Must(HaveValue).WithMessage("Email cannot be empty. (From Fluent - EmailValidator");

        Custom(vm =>
                   {
                       try
                       {
                           MailAddress m = new MailAddress(vm);

                           return null;
                       }
                       catch (FormatException ex)
                       {
                           return new ValidationFailure("",
                               "The email format is not valid. (From Fluent - EmailValidator)");
                       }

                   });
    }

IValidatorInterceptor for WebApi

Hi,
I was hoping to find a IValidatorInterceptor interface in the FluentValidation.WebApi namespace. I can only find it in FluentValidation.Mvc name space.
I tried using the inteface from the FluentValidation.Mvc but the implemented methods won’t get invoked in my WebApi scenario.
Is the IValidatorInterceptor feature only supported for Mvc controllers?
Thanks, for a brilliant library

Validation crashes for every rule (RuleFor(…).XXX())

Hi, I was trying to use my app after migrating fluentvalidation and I experienced a crash at the very creation of the RuleFor() of my Validator. This crashes for all the Rules and seems to be a bug on CreateDelegate, even though I could not understand why this would crash.

My structure is the following:

  • ViewModels (and validation) on a PCL Project, views made with Xamarin.Forms
  • Specific project for each platform.

This seems not to crash on Android.

The exception is an ArgumentException, with message "method argument length mismatch"

Here is the stacktrace for « .Email() »:

at System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure, Boolean allowClosed) [0x0011b] in corlib/System/Delegate.cs:293
at System.Reflection.MethodInfo.CreateDelegate (System.Type delegateType, System.Object target) [0x00000] in src\FluentValidation\Internal\Compatibility.cs:55
at FluentValidation.Resources.StaticResourceAccessorBuilder.GetResourceAccessor (System.Type resourceType, System.String resourceName) [0x00064] in \src\FluentValidation\Resources\IResourceAccessorBuilder.cs:42 
at FluentValidation.Resources.LocalizedStringSource..ctor (System.Type resourceType, System.String resourceName, IResourceAccessorBuilder resourceAccessorBuilder) [0x00006] in \src\FluentValidation\Resources\LocalizedStringSource.cs:40
at FluentValidation.Resources.LocalizedStringSource.CreateFromExpression (System.Linq.Expressions.Expression1 expression, IResourceAccessorBuilder resourceProviderSelectionStrategy) [0x00043] in \src\FluentValidation\Resources\LocalizedStringSource.cs:68
at FluentValidation.Validators.PropertyValidator..ctor (System.Linq.Expressions.Expression1 errorMessageResourceSelector) [0x00011] in \src\FluentValidation\Validators\PropertyValidator.cs:54
at FluentValidation.Validators.EmailValidator..ctor () [0x00000] in \src\FluentValidation\Validators\EmailValidator.cs:33
at FluentValidation.DefaultValidatorExtensions.EmailAddress[LoginPageViewModel] (IRuleBuilder`2 ruleBuilder) [0x00000] in \src\FluentValidation\DefaultValidatorExtensions.cs:127 `
at  --- MYCODE

And the stacktrace for « .Length(x, x) »:

at System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method, Boolean throwOnBindFailure, Boolean allowClosed) [0x0011b] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Delegate.cs:229 
at System.Delegate.CreateDelegate (System.Type type, System.Object firstArgument, System.Reflection.MethodInfo method) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Delegate.cs:293 
at System.Reflection.MethodInfo.CreateDelegate (System.Type delegateType, System.Object target) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MethodInfo.cs:174 
at FluentValidation.Internal.Compatibility.CreateGetter (System.Reflection.PropertyInfo property) [0x00000] in c:\\Projects\\FluentValidation\\src\\FluentValidation\\Internal\\Compatibility.cs:55 
at FluentValidation.Resources.StaticResourceAccessorBuilder.GetResourceAccessor (System.Type resourceType, System.String resourceName) [0x00064] in c:\\Projects\\FluentValidation\\src\\FluentValidation\\Resources\\IResourceAccessorBuilder.cs:42 
at FluentValidation.Resources.LocalizedStringSource..ctor (System.Type resourceType, System.String resourceName, IResourceAccessorBuilder resourceAccessorBuilder) [0x00006] in c:\\Projects\\FluentValidation\\src\\FluentValidation\\Resources\\LocalizedStringSource.cs:40 
at FluentValidation.Resources.LocalizedStringSource.CreateFromExpression (System.Linq.Expressions.Expression1 expression, IResourceAccessorBuilder resourceProviderSelectionStrategy) [0x00043] in c:\\Projects\\FluentValidation\\src\\FluentValidation\\Resources\\LocalizedStringSource.cs:68 
at FluentValidation.Validators.PropertyValidator..ctor (System.Linq.Expressions.Expression1 errorMessageResourceSelector) [0x00011] in c:\\Projects\\FluentValidation\\src\\FluentValidation\\Validators\\PropertyValidator.cs:54 
at FluentValidation.Validators.LengthValidator..ctor (Int32 min, Int32 max, System.Linq.Expressions.Expression`1 errorMessageResourceSelector) [0x00000] in c:\\Projects\\FluentValidation\\src\\FluentValidation\\Validators\\LengthValidator.cs:32 
at FluentValidation.Validators.LengthValidator..ctor (Int32 min, Int32 max) [0x00000] in c:\\Projects\\FluentValidation\\src\\FluentValidation\\Validators\\LengthValidator.cs:29 
at FluentValidation.DefaultValidatorExtensions.Length[LoginPageViewModel] (IRuleBuilder`2 ruleBuilder, Int32 min, Int32 max) [0x00000] in c:\\Projects\\FluentValidation\\src\\FluentValidation\\DefaultValidatorExtensions.cs:66 
at ----MYCODE

Downgrading to 5.5.0.0 fixed the issue, I had not enough time to investigate on why it crashed.

All seems to get down to https://github.com/JeremySkinner/FluentValidation/blob/master/src/FluentValidation/Internal/Compatibility.cs
Maybe this is a bug on mono ?

Hoping this helps you, do not hesitate to contact me for more infos on this.

More fluent validation tests

Hi there!

Great tool!

Could you extend your ValidationTestExtension to support more fluent validations like:

var validator = new ItemValidator();

validator.ShouldHaveChildValidator(x => x.SubItem, typeof(SubItemValidator));

 var testValidationResult = validator.TestValidate(new Item 
{ 
  IntProperty = 4, 
  StringProperty = "ww", 
  SubItem = new SubItem 
  { 
     IntProperty1 = 2, 
     StringProperty1 = "55" 
  } 
});

 testValidationResult.Which
                     .Property(x => x.SubItem)
                     .Property(x => x.IntProperty1)
                     .ShouldHaveError()
                     .When(x => x.ErrorCode == "inclusivebetween_error");

If you want I can send working sample project

Access to validator instance properties when using property validators in a rule

Hello,

When I define an AbstractValidator for a class, I want to be able to access my class properties as parameters for the property validators the same way I can pick the property to validate when calling RuleFor()

Example:

public class TextFieldValidator : AbstractValidator<TextField>
    {
        public TextFieldValidator()
        {
            When(t => !string.IsNullOrEmpty(t.Regex), () =>
            {
                // This doesn't work
                RuleFor(t => t.Value).Matches(t => t.Regex); 
            });
        }
    }

There is a workaround to do something like that?
Is it planned to add that feature in a future version?

MVC Validators not run if ModelState.IsValid == false due from other forms of validation.

Using MVC package id="FluentValidation.MVC5" version="5.1.0.0"

I have noticed that if the ModelState.IsValid == false then FV does not run. This creates a problem where if someone "forgets" to check modelstate status then the FV will be totally ignored.

Also, if there are both existing Model validation errors (from DataAnnotations for example) and potential FV errors, the user would have to POST twice to see the complete list of errors.

Is there config to control this?

RuleForEach fails with cast error when using MustAsync

Using MustAsync on a collection via RuleForEach throws a "Specified cast is not valid" exception when using "ValidateAsync" method on the validator. If you call "Validate" method validation succeeds. We're using these within async code in ASP.NET so we can't fall back on calling the validator synchronously.

The following code demonstrates the problem:

class Program
{
    static void Main(string[] args)
    {
        var validator = new AttributedValidatorFactory().GetValidator<Model>();
        var model = new Model
        {
            Ids = new Guid[0]
        };
        // this fails with "Specified cast is not valid" error
        var result = validator.ValidateAsync(model).Result;
    }
}

[Validator(typeof(ModelValidator))]
class Model
{
    public IEnumerable<Guid> Ids { get; set; }
}

internal class ModelValidator : AbstractValidator<Model>
{
    public ModelValidator()
    {
        RuleForEach(m => m.Ids)
            .MustAsync(g => Task.FromResult(true));
    }
}

AbstractComparison generates rules even when it shouldn't

If one uses one of the lambda-taking versions of the AbstractComparisonValidators, then the mvc adapter should not generate an unobtrusive rule, because the unobtrusive validators can only deal with values.

I was bitten by this because I need to have a field 0 < x < y. Due to the lack of InclusiveBetween that takes other properties as comparers, I need a GreaterThan and a LessThan rule, and MVC bombs out because it is trying to generate the range validator more than once.

System.AccessViolationException System.AccessViolationException

Hi,
We keep getting a number of errors in our system that always have a very similar stack trace. Have you seen anything like this before. We are using FluentValidation.5.5.0.0

Here is one stack trace.
An unhandled error has occurred in Nine.Saturn.Services.Campaigns.Service.CampaignEndpoint. | System.AccessViolationException System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at FluentValidation.Internal.Extensions.<>c__DisplayClass12.<CoerceToNonGeneric>b__0(Object x) in c:\Projects\FluentValidation\src\FluentValidation\Internal\Extensions.cs: line 108 at FluentValidation.Validators.PropertyValidatorContext.get_PropertyValue() in c:\Projects\FluentValidation\src\FluentValidation\Validators\PropertyValidatorContext.cs: line 53 at FluentValidation.Validators.PropertyValidator.Validate(PropertyValidatorContext context) in c:\Projects\FluentValidation\src\FluentValidation\Validators\PropertyValidator.cs: line 68 at FluentValidation.Internal.PropertyRule.<Validate>d__10.MoveNext() in c:\Projects\FluentValidation\src\FluentValidation\Internal\PropertyRule.cs: line 234 at System.Linq.Enumerable.<SelectManyIterator>d__142.MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList(IEnumerable1 source) at FluentValidation.AbstractValidator1.Validate(ValidationContext1 context) in c:\Projects\FluentValidation\src\FluentValidation\AbstractValidator.cs: line 113 at FluentValidation.DefaultValidatorExtensions.ValidateAndThrow(IValidator1 validator, T instance) in DefaultValidatorExtensions.cs: line 791
at Nine.Saturn.Services.Campaigns.DomainLogic.SpotOperations.SpotBookingOperationService.PlaceNewSpot(SpotParameters parameters, SpotOperationOptions operationOptions, BookingSource bookingSource) in SpotBookingOperationService.cs: line 172
at Nine.Saturn.Services.Campaigns.DomainLogic.SpotOperations.SpotBookingOperationService.PlaceBooking(NormalBookingRequest bookingRequest, Nullable`1 auditTransactionType, Boolean publishChangeNotifications) in SpotBookingOperationService.cs: line 143
at Nine.Saturn.Services.Campaigns.Service.CampaignEndpoint.PlaceBooking(NormalBookingRequest bookingRequest) in CampaignEndpoint.cs: line 516
at SyncInvokePlaceBooking(Object, Object[], Object[])
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(ref MessageRpc rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(ref MessageRpc rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(ref MessageRpc rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

and Here is another stack trace
An unhandled error has occurred in Nine.Saturn.Services.Campaigns.Service.CampaignEndpoint. | System.AccessViolationException System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at FluentValidation.Internal.Extensions.<>c__DisplayClass12.<CoerceToNonGeneric>b__0(Object x) in c:\Projects\FluentValidation\src\FluentValidation\Internal\Extensions.cs:line 108 at FluentValidation.Validators.PropertyValidatorContext.get_PropertyValue() in c:\Projects\FluentValidation\src\FluentValidation\Validators\PropertyValidatorContext.cs:line 53 at FluentValidation.Validators.PropertyValidator.Validate(PropertyValidatorContext context) in c:\Projects\FluentValidation\src\FluentValidation\Validators\PropertyValidator.cs:line 68 at FluentValidation.Internal.PropertyRule.<Validate>d__10.MoveNext() in c:\Projects\FluentValidation\src\FluentValidation\Internal\PropertyRule.cs:line 234 at System.Linq.Enumerable.<SelectManyIterator>d__142.MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at FluentValidation.AbstractValidator1.Validate(ValidationContext1 context) in c:\Projects\FluentValidation\src\FluentValidation\AbstractValidator.cs:line 113 at FluentValidation.DefaultValidatorExtensions.ValidateAndThrow[T](IValidator1 validator, T instance) in c:\Projects\FluentValidation\src\FluentValidation\DefaultValidatorExtensions.cs:line 791
at Nine.Saturn.Services.Campaigns.DomainLogic.SpotSearchService.SearchSpots(PagingContext pagingContext, SpotSearchRequest searchRequest) in d:\SourceControl\SaturnProd\Services\Campaigns.DomainLogic\SpotSearchService.cs:line 160
at SyncInvokeSearchSpots(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

`When` is executing action immediately

I don't think I'm using this wrong?

Pseudo:

public BaseValidator<T> {
  protected void AddRule() {
    // only when p.IsTrue
  }
}
public InheritedValidator<T> {
  ctor : base() {
    When(p => p.IsTrue, () => AddRule());
  }
}

MVC is creating instances of my validators (for MVC stuff) and I step through the code and AddRule is being called for every new instance. The code inside the predicate function is never hit, so I have no idea why my action is being executed. It should only be executing the Action when the predicate returns true, right?

Using 5.1 (MVC4).

Missing tags

Hello,

There are some missing tags in repository.
I understand it's not required.
But it's useful for example to get NuGet package of specified version, and fastly find the corresponding source code to checkout/download.

The following are versions and corresponding commits:

FluentValidation 5.6.2
98603d5

FluentValidation 5.6.1
9d765e2

FluentValidation 5.6.0
0aa198d

FluentValidation 5.5.0
911e3ca

FluentValidation 5.3.0
4555a33

FluentValidation 5.2.0
500e18b

FluentValidation 5.1.0
7756dc6

FluentValidation 5.0.0.1
190d853

FluentValidation 4.0.0.1
e7966e0

FluentValidation 3.4.6
dd78c32

FluentValidation 3.3.1
For 3.3.1 it seems that 3.3 tag is set to 3.3.1 commit.
3.3.1 - 18b7cc8
3.3 - 8b68b2e

PropertyRule should have an async version of InvokePropertyValidator.

CollectionPropertyRule inherits from PropertyRule and overrides the InvokePropertyValidator to set the correct property name.

When calling the validation async this override is never called on async validations.

The following method should be added to PropertyRule:

protected virtual Task<IEnumerable<ValidationFailure>> InvokePropertyValidatorAsync(ValidationContext context, IPropertyValidator validator, string propertyName, CancellationToken cancellation);

This should be called by PropertyRule.ValidateAsync when validating async property validations.

CustomizeValidationAttribute for Web API

The CustomizeValidationAttribute is tightly coupled to ASP.NET MVC. Is there a plan to make this accessible to ASP.NET Web API in the future?

All I am really trying to do is specify the RuleSet. Is there a different/better way to achieve this with Web API?

For example:
public IHttpActionResult Post([FromBody, CustomizeValidation(RuleSet = "Create")] Foo foo)
doesn't work.

Universal app 8.1 release build resources not found

From codeplex: https://fluentvalidation.codeplex.com/workitem/7214

"I was trying to use this library in a universal windows app 8.1, which is working fine until I use Release mode to deploy the app.
There seems to be a problem with the location of resource files, I believe microsoft changed the way these work (not sure). In universal apps resw files should be used instead of resx so far I know.

This is the following error I get when deploying:
Error: Compile filter argument specified non-existent file: ...\obj\ARM\Release\MSIL\da\FluentValidation.resources.dll
I checked the folder and indeed its not there, but it is in ...\obj\ARM\Release\MSIL\FluentValidation.resources.dll

Instead of each language in a separate folder.

Does anyone know a fix for this or will this require a new fluentvalidation package for universal apps?"

DelegateValidator causes a deadlock when running an async function synchronously.

The problem is the DelegateValidator is causing the current thread to wait for the result of the async task. This task may require the thread to be available so it can be posted back to. Both EF and ASP.Net using this technique of posting back to the original thread and if you are waiting on that thread you will get a deadlock.

public class DelegateValidator<T> : IValidationRule {
        ...
        public DelegateValidator(Func<T, ValidationContext<T>, Task<IEnumerable<ValidationFailure>>> asyncFunc) {
            this.asyncFunc = asyncFunc;
            func = (x, ctx) => this.asyncFunc(x, ctx).Result;
        }
       ...
}

Stephen Toub has a good post on making async calls synchronous. Basically he says try not to do it. But if you have to then run the task from a new thread (which you are doing) or use a message loop.
http://blogs.msdn.com/b/pfxteam/archive/2012/04/13/10293638.aspx.

The best option in this scenario is to run the task on a new threadpool thread then wait on that.

   func = (x, ctx) => Task.Run(()=> this.asyncFunc(x, ctx)).Result;

In reality users who use Async validation should just use ValidateAsync so we never have to switch to synchronous, but consumers of the validator may not always be aware of how the rules are configured.

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.