Posted
about 9 years
ago
by
ajitgoel
I am trying to ensure that a list has unique SSN's. I am getting the "Property name could not be automatically determined for expression element => element. Please specify either a custom property name by calling 'WithName'" error. Would we know
... [More]
what I am doing wrong here?
using FluentValidation;
using FluentValidation.Validators;
public class PersonsValidator : AbstractValidator<Persons>
{
public PersonsValidator()
{
this.RuleFor(element=>element).SetValidator(new SSNNumbersInHouseHoldShouldBeUnique<Persons>()).WithMessage("SSN's in household should be unique");
}
}
public class SSNNumbersInHouseHoldShouldBeUnique<T> : PropertyValidator
{
public SSNNumbersInHouseHoldShouldBeUnique(): base("SSN's in household should be unique")
{
}
protected override bool IsValid(PropertyValidatorContext context)
{
var persons = context.Instance as Persons;
try
{
if (persons == null)
{
return false;
}
var persons = persons.Where(
element => element.SSN.Trim().Length > 0);
var allSSNs = persons.Select(element => element.SSN.Trim());
if (allSSNs.Count() > allSSNs.Distinct().Count())
{
return false;
}
return true;
}
catch (Exception ex)
{
return false;
}
}
}
public class Persons : List<Person>
{}
public class Person
{
public string SSN{ get; set; }
}
[Less]
|
Posted
about 9 years
ago
by
ajitgoel
I am trying to ensure that a list has unique SSN's. I am getting the "Property name could not be automatically determined for expression element => element. Please specify either a custom property name by calling 'WithName'" error. Would we know
... [More]
what I am doing wrong here?
using FluentValidation;
using FluentValidation.Validators;
public class PersonsValidator : AbstractValidator
{
public PersonsValidator()
{
this.RuleFor(element=>element).SetValidator(new SSNNumbersInHouseHoldShouldBeUnique()).WithMessage("SSN's in household should be unique");
}
}
public class SSNNumbersInHouseHoldShouldBeUnique : PropertyValidator
{
public SSNNumbersInHouseHoldShouldBeUnique(): base("SSN's in household should be unique")
{
}
protected override bool IsValid(PropertyValidatorContext context)
{
var persons = context.Instance as Persons;
try
{
if (persons == null)
{
return false;
}
var persons = persons.Where(
element => element.SSN.Trim().Length > 0);
var allSSNs = persons.Select(element => element.SSN.Trim());
if (allSSNs.Count() > allSSNs.Distinct().Count())
{
return false;
}
return true;
}
catch (Exception ex)
{
return false;
}
}
}
public class Persons : List
{}
public class Person
{
public string SSN{ get; set; }
}
[Less]
|
Posted
about 9 years
ago
by
ajitgoel
I am trying to ensure that a list has unique SSN's. I am getting the "Property name could not be automatically determined for expression element => element. Please specify either a custom property name by calling 'WithName'" error. Would we know
... [More]
what I am doing wrong here?
using FluentValidation;
using FluentValidation.Validators;
public class PersonsValidator : AbstractValidator<Persons>
{
public PersonsValidator()
{
this.RuleFor(element=>element).SetValidator(new SSNNumbersInHouseHoldShouldBeUnique<Persons>()).WithMessage("SSN's in household should be unique");
}
}
public class SSNNumbersInHouseHoldShouldBeUnique<T> : PropertyValidator
{
public SSNNumbersInHouseHoldShouldBeUnique(): base("SSN's in household should be unique")
{
}
protected override bool IsValid(PropertyValidatorContext context)
{
var persons = context.Instance as Persons;
try
{
if (persons == null)
{
return false;
}
var persons = persons.Where(
element => element.SSN.Trim().Length > 0);
var allSSNs = persons.Select(element => element.SSN.Trim());
if (allSSNs.Count() > allSSNs.Distinct().Count())
{
return false;
}
return true;
}
catch (Exception ex)
{
return false;
}
}
}
public class Persons : List<Person>
{}
public class Person
{
public string SSN{ get; set; }
}
[Less]
|
Posted
over 9 years
ago
by
JeremyS
Hi Michael,
FluentValidation has moved to GitHub - in future please post your questions over there rather than on codeplex: https://github.com/jeremyskinner/fluentvalidation/issues
So at the moment Dependent Rules aren't compatible with rulesets
... [More]
- I'll get this fixed.
(Additionally, FluentValidation requires that the root-level object being validated is not-null, so your example using RuleFor(o => o).NotNull() won't actually work, but the concept is right)
[Less]
|
Posted
over 9 years
ago
by
JeremyS
Hi Michael,
FluentValidation has moved to GitHub - in future please post your questions over there rather than on codeplex: https://github.com/jeremyskinner/fluentvalidation/issues
So at the moment Dependent Rules aren't compatible with rulesets
... [More]
- I'll get this fixed.
(Additionally, FluentValidation requires that the root-level object being validated is not-null, so your example using RuleFor(o => o).NotNull() won't actually work, but the concept is right)
[Less]
|
Posted
over 9 years
ago
by
infinitimods
Dear Jeremy,
I have been reading about dependent rules here:
https://github.com/JeremySkinner/FluentValidation/issues/65
From my understanding, a dependent rule will execute only if the preceding rules succeed. However, I cannot get this to
... [More]
work. Ex:
RuleFor(o => o).NotNull().WithMessage("Customer cannot be null")
.DependentRules(d =>
{
d.RuleFor(x => x.FirstName).NotEmpty().WithMessage("First name cannot be empty");
// Other code to execute here
});
If I pass in a customer object which is not null, I expect to validate the first name. However, no validation is fired. What am I doing wrong or what am I missing here?
Thank you for your help,
Michael
[Less]
|
Posted
over 9 years
ago
by
infinitimods
Dear Jeremy,
I have been reading about dependent rules here:
https://github.com/JeremySkinner/FluentValidation/issues/65
From my understanding, a dependent rule will execute only if the preceding rules succeed. However, I cannot get this to
... [More]
work. Ex:
RuleFor(o => o).NotNull().WithMessage("Customer cannot be null")
.DependentRules(d =>
{
d.RuleFor(x => x.FirstName).NotEmpty().WithMessage("First name cannot be empty");
// Other code to execute here
});
If I pass in a customer object which is not null, I expect to validate the first name. However, no validation is fired. What am I doing wrong or what am I missing here?
Thank you for your help,
Michael
[Less]
|
Posted
over 9 years
ago
by
JeremyS
Hi, looks like this is an issue with your configuration with Ninject - I'm afraid I can't help with that. You'd need to ask the Ninject team for help.
Please note that FluentValidation moved to github a while back - for any future questions please use the issue tracker on
github.com/JeremySkinner/FluentValidation
Thanks.
|
Posted
over 9 years
ago
by
patelajk2
Hi
I am getting an error with trying to create a generic IOC.
I have a ValidationService which will be used to validate my models:
public class ValidationService : IValidationService
{
private readonly IValidatorFactory _validatorFactory;
... [More]
public ValidationService(IValidatorFactory validatorFactory)
{
_validatorFactory = validatorFactory;
}
public ValidationResult Validate<T>(T entity) where T : class
{
var validator = _validatorFactory.GetValidator<T>();
var result = validator.Validate(entity);
return result;
}
}
I also have a factory:
public class NinjectValidatorFactory : ValidatorFactoryBase
{
private readonly IKernel Container;
public NinjectValidatorFactory(IKernel container)
{
Container = container;
}
public override IValidator CreateInstance(Type validatorType)
{
// errors here!!
var x = Container.Get(validatorType) as IValidator;
return x;
}
}
I have also created by bindings via a NinjectModule:
public override void Load()
{
Bind<IWriteRespository>().To<WriteRepository>();
Bind<IReadRepository>().To<ReadRepository>();
Bind<IContextFactory>().To<ContextFactory>();
Bind<IWriteDataHelper>().To<WriteDataHelper>();
Bind<IValidationService>().To<ValidationService>();
Bind<IValidator<FundRecordModel>>().To<FundRecordModelValidator>();
Bind<IValidatorFactory>().To<NinjectValidatorFactory>();
}
When I try to Validate:
public void AddFundRecord(FundRecordModel model)
{
try
{
var results = _validationService.Validate(model);
}
I get an error:
Error activating IValidator{FundRecordModel}\r\nNo matching bindings are available, and the type is not self-bindable.\r\nActivation path:\r\n
I have double checked everything but can't seem to find out what is wrong...
Any help would be greatly appreciated.
Thanks
[Less]
|
Posted
over 9 years
ago
by
bkothe
I have a question regarding testing a specific rule for a property triggered a failure in the validation. Has there ever been any thought to adding "expected message" to the test extensions? Example...
Say you have the following validator
... [More]
public class UserValidator : AbstractValidator<User>
{
public const string DuplicateEmailMessage = "Email address already exists.";
public const string EmailLengthMessage = "Email address must be between {MinLength} and {MaxLength} characters.";
public const string InvalidEmailMessage = "Email address is not valid.";
public UserValidator(IEnumerable<User> users)
{
RuleFor(x => x.FirstName).NotEmpty().Length(1, 25);
RuleFor(x => x.LastName).NotEmpty().Length(1, 25);
RuleFor(x => (string)x.EmailAddress)
.NotEmpty().WithMessage(EmailLengthMessage)
.Length(5, 254).WithMessage(EmailLengthMessage)
.Must(x => x.IsValidEmailAddress()).WithMessage(InvalidEmailMessage)
.Must((user, emailAddress) =>
!users.Any(x =>
x.EmailAddress.Address == emailAddress &&
x.Id != user.Id))
.WithMessage(DuplicateEmailMessage);
}
}
To test that duplicate emails are being caught the object would have to be setup to pass all validation prior to email address which makes for an ugly test.
var result = userValidator.Validate(new User
{
Id = Guid.NewGuid(),
FirstName = "Neil",
LastName = "Peart",
EmailAddress = new EmailAddress(duplicateEmailAddress)
});
result.IsValid.ShouldBeFalse();
result.Errors.First().ErrorMessage.ShouldEqual(UserValidator.DuplicateEmailMessage);
The extensions provided with FluentValidation can be used to eliminate the need to setup all the properties correctly like so
validator.ShouldHaveValidationErrorFor(x => x.EmailAddress, "[email protected]")
But if the email address is typed incorrectly in the test, the test could still pass if one of the other rules for email address was triggered. So the test would pass but not for the reason expected. It would be nice to check that the message and/or state being returned is the message/state expected. So something like this...
validator.ShouldHaveValidationErrorFor(x => x.EmailAddress, "[email protected]", UserValidator.DuplicateEmailMessage)
Does the question make sense? Is there a different/better way I should handle this situation Would it be possible to add that functionality? I could probably create my own extension method to handle this situation but it seems like it might be a good addition to the built in test extensions. I initially wrote this with the message in mind but if the message includes any placeholders it might not work which is why I also mentioned using expected state instead of expected message. Thoughts?
[Less]
|