Quantcast
Channel: Fluent Validation for .NET
Viewing all 1917 articles
Browse latest View live

New Post: merge Viewmodel with model validation

$
0
0
Hi,

Im confused. I have a few rules for two models:

Validation for model Sistemas:
public class SistemasMetadata : AbstractValidator<Sistemas>
    {
        public SistemasMetadata()
        {
            RuleFor(s => s.IdSistemaDiccionario)
                .NotNull().WithMessage("* Requerido")
                .GreaterThan(0).WithMessage("* Requerido")
                .NotEmpty().WithMessage("* Requerido");
        }
    }
Validation for model SistemasDiccionario:
public class SistemasDiccionarioMetadata : AbstractValidator<SistemasDiccionario>
    {
        public SistemasDiccionarioMetadata()
        {
            RuleFor(sd => sd.Nombre)
                .NotNull().WithMessage("* Requerido")
                .Must((sd, nombre) => NombreUnico(sd, nombre)).WithMessage("* Nombre existente")
                .Length(1, 200).WithMessage("* Longitud máxima de 200 caracteres");

            RuleFor(sd => sd.Descripcion)
                .Length(0, 500).WithMessage("* Longitud máxima de 500 caracteres");
        }

        private bool NombreUnico(SistemasDiccionario _sd, string nombre)
        {
            //existing logic its ok...
        }
    }
And i have a ViewModel with properties that referencing a model:
    public class SistemasConfiguracionViewModel 
    {
        public Sistemas Sistemas { get; set; }
        public SistemasDiccionario SistemasDiccionario { get; set; }

        //existing logic its ok

     }
And then, i have a view with above view model. In this view i have a check-box to hide or show some part of view. In first part, i just want get a property of "Sistemas". In second part i just want get a property of "SistemasDiccionario".

This is my View:
@model <<NameSpaceItsOk>>.ViewModels.SistemasConfiguracionViewModel

<form id="form" method="post" action="">

<!-- HIDE OR SHOW -->
        <div id="divCrear"> 
            <p>
                @Html.LabelFor(model => model.Sistemas.IdSistemaDiccionario, "Diccionario")
                @Html.TextBoxFor(model => model.Sistemas.IdSistemaDiccionario)
                
            </p>
        </div>

<!-- HIDE OR SHOW -->
        <div id="divCrearNuevo" style="display: none;"> 
            <p>
                @Html.LabelFor(model => model.SistemasDiccionario.Nombre)
                @Html.TextBoxFor(model => model.SistemasDiccionario.Nombre)
            </p>
            <p>
                @Html.LabelFor(model => model.SistemasDiccionario.Descripcion, "Descripción")
                @Html.TextBoxFor(model => model.SistemasDiccionario.Descripcion)
            </p>
        </div>
        <p style="text-align: center;">
            <input type="button" id="btnSubmit" class="boton" value="Crear" />
        </p>
</form>
When i hide one of this part and send httppost to my controller, the ModelState is invalid, because both properties ( i.e. both models ) are validated.

So, How can I exclude one of this validations? Or, how can i handle this situation?

Thank you in advance. Regards!


M.S.

New Post: merge Viewmodel with model validation

$
0
0
I resolve that with autoMapper.

Thank you.

Created Unassigned: Chaining validators causes exception [7156]

$
0
0
Consider this:

```
this.RuleFor(x => x.Stream).NotNull().Must(x => x.Length >= 10);
```

When Stream is null, the validator should fail immediately, however, it continues with the next rule and tries to access Length of a null object, therby causing object reference error.

Commented Unassigned: Chaining validators causes exception [7156]

$
0
0
Consider this:

```
this.RuleFor(x => x.Stream).NotNull().Must(x => x.Length >= 10);
```

When Stream is null, the validator should fail immediately, however, it continues with the next rule and tries to access Length of a null object, therby causing object reference error.
Comments: This is correct. If you want to stop the Must rule from running in this case, then you can either add a When clause or set the CascadeMode of the rule to StopOnFirstFailure.

Commented Unassigned: Chaining validators causes exception [7156]

$
0
0
Consider this:

```
this.RuleFor(x => x.Stream).NotNull().Must(x => x.Length >= 10);
```

When Stream is null, the validator should fail immediately, however, it continues with the next rule and tries to access Length of a null object, therby causing object reference error.
Comments: I figured... But something doesn't feel right about that. I mean the whole point of being able to chain stuff runs counterintuitive. Maybe this is just me but the above scenario should behave like this: ``` if(x.Stream == null || x.Stream.Length < 10) // fail validation ``` Setting CascadeMode is an all or nothing solution and although I want it to stop in this rule, I may have several others that I want to validate in one shot.

Commented Unassigned: Chaining validators causes exception [7156]

$
0
0
Consider this:

```
this.RuleFor(x => x.Stream).NotNull().Must(x => x.Length >= 10);
```

When Stream is null, the validator should fail immediately, however, it continues with the next rule and tries to access Length of a null object, therby causing object reference error.
Comments: Hi CascadeMode can be set for an individual call for RuleFor - you don't need to set it globally: RuleFor(x => x.Surname).Cascade(CascadeMode.StopOnFirstFailure).NotNull().NotEqual("foo"); Rules in FV are more like this: ``` if(x.Stream == null) { //fail validation } if(x.Stream.Length < 10) { // fail validation ``` Validators in FluentValidation execute in isolation - they have onside effects on anything else in the chain (the only exception being if they fail when the cascade is set to StopOnFirstFailure). Changing this for NotNull would make this inconsistent, also isn't something I plan to change.

New Post: non-generic, non-expressionTree RuleFor

$
0
0
Is there any way to define rules without expression tree
RuleFor(typeof(DtoBase), "propName");

New Post: non-generic, non-expressionTree RuleFor

$
0
0
Hi

No, sorry. The entire point of FluentValidation is to define strongly-typed rules using generics and lambdas.

Jeremy

New Post: non-generic, non-expressionTree RuleFor

$
0
0
Thanks
We are just evaluating validation frameworks
Unfortunately, it's not suitable for dynamic types

New Post: Parallelism

$
0
0
I have noticed the same effect when using the SetCollectionValidator with v4.0. Was this ever included or is there intent to include it or something similar to produce the parallelism?

Source code checked in, #93f005153734fc763fb385b5bac2d6e4a8869360

$
0
0
Merge branch 'master' of https://git01.codeplex.com/forks/ninjagumby/FluentValidationLocalization

Created Unassigned: Pass validation instance along .SetValidator() [7157]

$
0
0
Good evening,

What I am missing with the current .SetValidator(..) implementations is a way to pass along / work with the validation context's instance of T - is there any way to do this? E.g. that sub-validator might require information/data from the parent object of the property passed along for validation

Commented Unassigned: Pass validation instance along .SetValidator() [7157]

$
0
0
Good evening,

What I am missing with the current .SetValidator(..) implementations is a way to pass along / work with the validation context's instance of T - is there any way to do this? E.g. that sub-validator might require information/data from the parent object of the property passed along for validation
Comments: ... is this possible in any currently? Thanks! -J

Commented Unassigned: Pass validation instance along .SetValidator() [7157]

$
0
0
Good evening,

What I am missing with the current .SetValidator(..) implementations is a way to pass along / work with the validation context's instance of T - is there any way to do this? E.g. that sub-validator might require information/data from the parent object of the property passed along for validation
Comments: This isn't supported out of the box, but you can add an extension method for it pretty easily: ``` namespace FluentValidation.Demo { using System; using System.Collections.Generic; using FluentValidation.Validators; using FluentValidation.Results; public class LazyValidatorAdaptor<T, TProperty> : NoopPropertyValidator { Func<T, IValidator<TProperty>> _func; public LazyValidatorAdaptor(Func<T, IValidator<TProperty>> func) { _func = func; } public override IEnumerable<ValidationFailure> Validate(PropertyValidatorContext context) { var validator = _func((T)context.Instance); var adaptor = new ChildValidatorAdaptor(validator); return adaptor.Validate(context); } } public static class MyExtensions { public static IRuleBuilderOptions<T, TProperty> SetValidator<T, TProperty>(this IRuleBuilder<T, TProperty> rule, Func<T, IValidator<TProperty>> validatorThunk) { return rule.SetValidator(new LazyValidatorAdaptor<T, TProperty>(validatorThunk)); } } } ``` Then you can use it like this: ``` RuleFor(x => x.SomeProperty).SetValidator(x => new ChildValidator(x)); ```

Commented Unassigned: Pass validation instance along .SetValidator() [7157]

$
0
0
Good evening,

What I am missing with the current .SetValidator(..) implementations is a way to pass along / work with the validation context's instance of T - is there any way to do this? E.g. that sub-validator might require information/data from the parent object of the property passed along for validation
Comments: Perfect, thanks Jeremy! (sorry for the numerous typos above, was somewhat on the jump yesterday).

New Post: FluentValidation + MVC 4 Automatic Integration / Enable on Some Controllers - Not Entire Project

$
0
0
Hello,

I want to thank you for a great library.

I am new to MVC / MVC 4 and I want to integrate FluentValidation into an existing MVC 4 project.

There is existing code with validation using Data Annotations on some ViewModels and it is checked in a few controllers using the ModelState.IsValid property.

I would like to integrate FV into the project for use in all new ViewModels and new Controllers.

Can I follow the "Integration with ASP.NET MVC" instructions - or will this disrupt the existing validations (modelbinding?) done with Data Annotations and ModelState.IsValid?

Am I able to integrate FV into the MVC Model Binding infrastructure on a per-controller basis? If so, how?

I know there is a way to validate manually: for each controller - instantiating a validator, then using the AddToModelState extension method to copy over the errors.

I was hoping I could do the automatic integration and leave the legacy code still operable. I am a little green on the DefaultModelBinder and how I can allow some controllers to use the existing Model Validator Provider and others to use the FluentValidationModelValidatorProvider.

Thank you again for the nice project and the support and documentation. Have a great day!

New Post: FluentValidation + MVC 4 Automatic Integration / Enable on Some Controllers - Not Entire Project

$
0
0
Hi

Can I follow the "Integration with ASP.NET MVC" instructions - or will this disrupt the existing validations (modelbinding?) done with Data Annotations and ModelState.IsValid?

Yes you can follow the instructions in "Integration with ASP.NET MVC". This does not prevent DataAnnotations-based validation from working.

The only thing to be aware of, is that calling FluentValidationModelValidatorProvider.Configure will set DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes to false. This is required for FluentValidation's MVC integration to work properly, so it'll be worth checking whether you have any DataAnnotations-based rules that requires this being set to true.

Am I able to integrate FV into the MVC Model Binding infrastructure on a per-controller basis? If so, how?

No, integration is done at the global level, but this shouldn't really have an impact. MVC gives each validator provider a chance to perform validation, so it will fall back to DataAnnotations if you haven't defined any validators using FluentValidation.

Jeremy

New Post: Handling inheritance

$
0
0
I have implemented the above example for inheritance, the validation worked correctly but the error messages are not being submitted properly to the screen.
Only the field marked in red and the error messages are not displayed on the screen, I noticed that they are not being displayed during the assembly of the display html as well.
Any idea what might be missing?
Tks

Created Unassigned: Set Validator for particular values inside an indexed Property? [7158]

$
0
0
Good afternoon,

I have another question regarding specifying a custom validator, particularly I have an IEumerable/Collection and I want to set a validator of type A for one of the entries and another validator of type B for again.. another entry in that collection (and basically ignore other entries).

This does not work (as it throws an exception saying 'Nested validators can only be used with Member Expressions.'):

```
this.RuleFor(teamProject => teamProject.Categories[categoryName]).SetValidator(validatorInstanceForCategoryWithProvidedCategoryName);
```

.. but how could/would I do that instead?

Thanks!
-J

New Post: Handling inheritance

$
0
0
This code that was implemented:

[FluentValidation.Attributes.Validator(typeof(AddressValidator))]
public class Address : BaseEntity
{
    public string City { get; set; }

    public string StreetComplement { get; set; }

    public string Country { get; set; }

    public string District { get; set; }

    public string Street { get; set; }

    public string StreetNumber { get; set; }

    public string State { get; set; }

    [MaskHtml(CssClass = "cep")]
    public string ZipCode { get; set; }

    public string Reference { get; set; }
}

[FluentValidation.Attributes.Validator(typeof(ShippingAddressValidator))]
public class ShippingAddress : Address
{
    public int Id { get; set; }

    public string ShippingRecipientName { get; set; }

    public string Local { get; set; }

    public string PhoneAreaCode { get; set; }

    public string PhoneNumber { get; set; }

    public string PhoneAreaCodeAlternative { get; set; }

    public string PhoneNumberAlternative { get; set; }

    public static explicit operator ShippingAddress(EnderecoEntrega enderecoEntrega)
    {
        return new ShippingAddress
        {
            ShippingRecipientName = enderecoEntrega.nome,
            Local = enderecoEntrega.local,
            Street = enderecoEntrega.logradouro,
            StreetNumber = enderecoEntrega.numero,
            StreetComplement = enderecoEntrega.complemento,
            District = enderecoEntrega.bairro,
            City = enderecoEntrega.cidade,
            State = enderecoEntrega.estado,
            Country = enderecoEntrega.pais,
            ZipCode = enderecoEntrega.cep,
            PhoneNumber = enderecoEntrega.telefone,
            PhoneAreaCode = enderecoEntrega.ddd_telefone,
            PhoneNumberAlternative = enderecoEntrega.celular,
            PhoneAreaCodeAlternative = enderecoEntrega.ddd_celular
        };
    }
}

public class AddressBaseValidator<TAddress> : AbstractValidator<TAddress> where TAddress : Address
{
    public AddressBaseValidator()
    {
        RegisterRules();
    }

    private void RegisterRules()
    {
        RuleFor(model => model.City)
            .NotNull().WithLocalizedMessage(() => Resources.Address.City)
            .NotEmpty().WithLocalizedMessage(() => Resources.Address.City)
            .Length(1, 100).WithLocalizedMessage(() => Resources.Address.CityLength);

        RuleFor(model => model.StreetComplement)
            .Length(0, 255).WithLocalizedMessage(() => Resources.Address.ComplementLength);

        RuleFor(model => model.Country)
            .Length(0, 3).WithLocalizedMessage(() => Resources.Address.CountryLength);

        RuleFor(model => model.District)
            .NotNull().WithLocalizedMessage(() => Resources.Address.District)
            .NotEmpty().WithLocalizedMessage(() => Resources.Address.District)
            .Length(1, 80).WithLocalizedMessage(() => Resources.Address.DistrictLength);

        RuleFor(model => model.Street)
            .NotNull().WithLocalizedMessage(() => Resources.Address.Street)
            .NotEmpty().WithLocalizedMessage(() => Resources.Address.Street)
            .Length(1, 200).WithLocalizedMessage(() => Resources.Address.StreetLength);

        RuleFor(model => model.StreetNumber)
            .NotNull().WithLocalizedMessage(() => Resources.Address.StreetNumber)
            .NotEmpty().WithLocalizedMessage(() => Resources.Address.StreetNumber)
            .Length(1, 10).WithLocalizedMessage(() => Resources.Address.StreetNumberLength);

        RuleFor(model => model.State)
            .NotNull().WithLocalizedMessage(() => Resources.Address.State)
            .NotEmpty().WithLocalizedMessage(() => Resources.Address.State)
            .Length(1, 20).WithLocalizedMessage(() => Resources.Address.StateLength);

        RuleFor(model => model.ZipCode)
            .NotNull().WithLocalizedMessage(() => Resources.Address.ZipCode)
            .NotEmpty().WithLocalizedMessage(() => Resources.Address.ZipCode)
            .Length(1, 10).WithLocalizedMessage(() => Resources.Address.ZipCodeLength);
    }
}

public class AddressValidator : AddressBaseValidator<Address>
{
    public AddressValidator()
    {
    }
}

public class ShippingAddressValidator : AddressBaseValidator<ShippingAddress>
{
    public ShippingAddressValidator()
    {
        RegisterRules();
    }

    private void RegisterRules()
    {
        RuleFor(model => model.PhoneAreaCode)
            .Length(0, 5).WithLocalizedMessage(() => Resources.Address.AreaCodeLength);

        RuleFor(model => model.PhoneNumber)
            .Length(0, 15).WithLocalizedMessage(() => Resources.Address.PhoneLength);

        RuleFor(model => model.PhoneAreaCodeAlternative)
            .Length(0, 5).WithLocalizedMessage(() => Resources.Address.CellphoneAreaCodeLength);

        RuleFor(model => model.PhoneNumberAlternative)
            .Length(0, 15).WithLocalizedMessage(() => Resources.Address.CellphoneLength);

    }
}

public class PolymorphicCollectionValidator<TBaseClass> : FluentValidation.Validators.NoopPropertyValidator
{
    Dictionary<Type, IValidator> derivedValidators = new Dictionary<Type, IValidator>();
    IValidator<TBaseClass> baseValidator;

    public PolymorphicCollectionValidator(IValidator<TBaseClass> baseValidator)
    {
        this.baseValidator = baseValidator;
    }

    public PolymorphicCollectionValidator<TBaseClass> Add<TDerived>(IValidator<TDerived> derivedValidator) where TDerived : TBaseClass
    {
        derivedValidators[typeof(TDerived)] = derivedValidator;
        return this;
    }

    public override IEnumerable<ValidationFailure> Validate(FluentValidation.Validators.PropertyValidatorContext context)
    {
        var collection = context.PropertyValue as IEnumerable<TBaseClass>;

        // bail out if the property is null or the collection is empty
        if (collection == null) return Enumerable.Empty<ValidationFailure>();
        if (!collection.Any()) return Enumerable.Empty<ValidationFailure>();

        // get the first element out of the collection and check its real type. 
        var actualType = collection.First().GetType();

        IValidator derivedValidator;

        if (derivedValidators.TryGetValue(actualType, out derivedValidator))
        {
            // we found a validator for the specific subclass. 
            var collectionValidtor = new ChildCollectionValidatorAdaptor(derivedValidator);
            return collectionValidtor.Validate(context);
        }

        // Otherwise fall back to the validator for the base class.
        var collectionValidator = new ChildCollectionValidatorAdaptor(baseValidator);
        return collectionValidator.Validate(context);
    }
}

public class ConvidadoModelValidator : AbstractValidator<ConvidadoModel>
{
    public ConvidadoModelValidator()
    {
        RuleFor(m => m.Customer).SetValidator(new CustomerValidator());
        RuleFor(x => x.ShippingAddresses).SetValidator(new PolymorphicCollectionValidator<Address>(new AddressValidator()).Add<ShippingAddress>(new ShippingAddressValidator()));
    }

    public override ValidationResult Validate(ConvidadoModel instance)
    {
        var validationResult = base.Validate(instance);
        foreach (var item in validationResult.Errors)
        {
            instance.AddError(item.PropertyName, item.ErrorMessage);
        }
        return validationResult;
    }
}
The problem only occurs on the client side, the validation messages are not displayed correctly.

Please give me a hint.

Tks.
Viewing all 1917 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>