New Post: NullReferenceException using FluentValidation in MVC3
New Post: Dependent Validations
How can I define a Rule for the following scenario:
The customer has a property - customerType, and according to that, there must be a validation to check if the home country he picked is in a lista of values.
I've tried the following:
RuleFor(customer => customer.HomeCountry).NotEmpty().Must(IsValidCountryCategory(customerType, homeCountryCategory)).WithMessage("Select a valid country"); private bool IsValidCountryCategory(string customerType, string homeCountryCategory) { var ValidCountries = new List<string>(); //categorias v�lidas para clientes do tipo R ValidCountries.Add("B"); ValidCountries.Add("E"); ValidCountries.Add("O"); ValidCountries.Add("P"); return ValidCountries.Contains(homeCountryCategory); }
But in the rule definition, i'm getting the following error:
'FluentValidation.IRuleBuilderOptions<ConsoleApplication1.Customer,string>' does not contain a definition for 'Must' and the best extension method overload 'FluentValidation.DefaultValidatorExtensions.Must<T,TProperty>(FluentValidation.IRuleBuilder<T,TProperty>, System.Func<T,TProperty,FluentValidation.Validators.PropertyValidatorContext,bool>)' has some invalid arguments
Can you help me ? waht am I doing wrong ?
Best regards.
New Post: Using FluentValidation in WPF application?
Hello. Is this library works with WPF applications? if yes do you have any article about implementing it?
I'm using WPF and EF Code First.
thanks.
New Post: Using FluentValidation in WPF application?
Hi
Yes, FluentValidation will work fine in a WPF application - it's designed for validating objects and is not tied to any particular UI platform. I don't have any articles for using it with WPF I'm afraid, sorry, but typically you'd use it to validate the viewmodel instance that your view is bound to, and then somehow report the errors back (I'm not particularly familiar with WPF development, so I can't advise on the best way of displaying the errors, but hopefully the general principle makes sense)
Jeremy
New Post: Dependent Validations
Hi
Your method declaration doesn't look quite right. There are two overloads for Must - one accepts the property value, the other accepts the instance being validated and the property value. In your example, neither of these are being used. I'd suggest taking a look at the documentation for Must:
Here's a modified version that should compile:
RuleFor(customer => customer.HomeCountry).NotEmpty().Must(IsValidCountryCategory).WithMessage("Select a valid country"); private bool IsValidCountryCategory(Customer customer, string homeCountry) { // From here you can now access properties of the Customer directly }
New Post: Dependent Validations
Thank you very much jeremy's.
That was it! :)
Going to search now, if it is possible to have the rules in xml files ;)
Best regards.
New Post: Testing an "InEnumValidator" custom validator
I created a custom validator, which tests that an enum is valid, that means it is within the enum's range of valid values:
[DebuggerStepThrough]
public class IsInEnumValidator<T> : PropertyValidator {
public IsInEnumValidator() : base("Property {PropertyName} it not a valid enum value.") { }
protected override bool IsValid(PropertyValidatorContext context) {
if (!typeof(T).IsEnum) return false;
return Enum.IsDefined(typeof(T), context.PropertyValue);
}
}
And an extension method for chaining validators:
[DebuggerStepThrough]
public static IRuleBuilderOptions<T, TProperty> IsInEnum<T, TProperty>(this IRuleBuilder<T, TProperty> ruleBuilder) {
return ruleBuilder.SetValidator(new IsInEnumValidator<TProperty>());
}
To use it:
RuleFor(x => x.Day).IsInEnum<DayOfWeek>();
Now I need to test the validator- not test my data with the validator, but to test the validator itself. The library has quite a bit of stuff going on, so I can't figure out how to do it. Can someone give me a pointer? I use NUnit.
New Post: Testing an "InEnumValidator" custom validator
Would be cool if this method could be in the library itself
New Post: Find duplicate items in Collection
Hi
I am new to fluent validation and facing the problem to find the duplicate item in the collection. I am using MVP.
I just wanted to validate the user code in the UserPersonalCollection before adding it to the collection. Add new user only when it does not exists in UserPersonalCollection.
Here is the sample code of View, Presenter and Validator
-------------
public interface IUserView { string UserName { get; set; } string UserCode { get; set; } string UserPassword { get; set; } UserPersonalCollection Users { get; set; } event EventHandler AddUser; event EventHandler LoadUser; }
Presenter
-------------public class UserPresenter { IUserView View; UserPersonalCollection m_users; public UserPresenter(IUserView view) { View = view; View.AddUser += new EventHandler(View_AddUser); View.LoadUser += new EventHandler(View_LoadUser); m_users = new UserPersonalCollection(); } private void View_LoadUser(object sender, EventArgs e) { } private void View_AddUser(object sender, EventArgs e) { UserValidator validator = new UserValidator(); ValidationResult result = validator.Validate(View); if (result.IsValid == true) { m_users.Add(new UserPersonal { Code = View.UserCode, Name = View.UserName, Password = View.UserPassword }); View.Users = m_users; } } }
Validator
---------------
public class UserValidator : AbstractValidator<IUserView> { public UserValidator() { RuleFor(x => x.UserCode).NotNull().NotEmpty().WithMessage("Please select user code"); RuleFor(x => x.UserName).NotNull().NotEmpty().WithMessage("Please select user name"); RuleFor(x => x.UserPassword).NotNull().NotEmpty().WithMessage("Please select user password"); } }Any help would appreciated.
Thanks in advance
Shashi
New Post: Validating enums with a custom FluentValidator validator
Hi
I'm not entirely sure I understand the purpose of your custom validator. If you're validating a property whose value is of type DayOfWeek, then by its very definition it will already be within the range of values specified in the DayOfWeek enum, so there's no need for this validator. Or am I missing something?
To test a validator itself, simply create a validator class for a fake object and then feed it the data that should cause either validation to pass or fail, and assert the results. There are plenty of examples of this in FluentValidation's own test project - I'd suggest having a look at those as a starting point. Here's a simple example that tests the NotNull validator works as expected:
[TestFixture] public class NotNullTester { public class Person { public string Surname { get; set; } } public class TestValidator : AbstractValidator<Person> { } [Test] public void NotNullValidator_should_pass_if_value_has_value() { var validator = new TestValidator(); validator.RuleFor(x => x.Surname).NotNull(); var result = validator.Validate(new Person{Surname = "Foo"}); Assert.IsTrue(result.IsValid); } [Test] public void NotNullValidator_should_fail_if_value_is_null() { var validator = new TestValidator(); validator.RuleFor(x => x.Surname).NotNull(); var result = validator.Validate(new Person { Surname = null }); Assert.IsFalse(result.IsValid); } // etc etc }
New Post: Find duplicate items in Collection
Hi
FluentValidation is designed to validate the values of properties that have already been set on a particular object. In this case, you're validating the View, so checking whether the user is already in UserPersonalCollection isn't something that can be handled by your UserValidator, as this is outside of the UserView for which your validator is defined. The simplest thing to do would be not to use FluentValidation for this particular rule - just perform the check manually.
New Post: Validating enums with a custom FluentValidator validator
The reason for the custom validator is that you can cast any int to an enum:
enum DaysOfWeek { Mon=0, Tue, Wed, Thu, Fri, Sat, Sun }
DaysOfWeek thisisallowed = (DaysOfWeek)100;
DaysOfWeek soisthis = (DaysOfWeek)(-1);
This is problematic when the int comes from a GET/POST, and is subject to tampering. So I want to ensure that it is not just an int, but that it is within the enum's actual range. For DaysOfWeek its range is 0..6. If the input is 7 then the validation should fail.
This is important because these sort of ints are used as IDs in repository methods, etc. So the value must be in the appropriate range.
Though I can't even get that far, as (see Q), I can't it to work generically. Not sure why?
New Post: Validating enums with a custom FluentValidator validator
Ah, I see what you mean.
Because of type inference, you shouldn't have to specify either of the generics - you should just be able to say RuleFor(x => x.Property).IsInEnum() and the type inference will work out the type of TProperty as this is the same type as the property already.
Jeremy
New Post: Validating enums with a custom FluentValidator validator
So obvious! Anyways I changed the validator so it also works for nullable enums:
protected override bool IsValid(PropertyValidatorContext context) {
Type t = typeof(T).IsGenericType
? Nullable.GetUnderlyingType(typeof(T))
: typeof(T);
// if T is not an enum to begin with, then must fail without checking anything
if (!t.IsEnum) return false;
// valid if T is nullable and value is null
if (typeof(T).IsGenericType && (_context.PropertyValue == null)) return true;
// valid if it fits within the enum
return Enum.IsDefined(t, context.PropertyValue);
}
And I got the testing code to work too. Thanks for the pointers.
This is really useful in webforms/mvc enviroment for sanitizing inputs. Please consider adding it to the library the next time you make some mods. Awesome library, thanks!
New Post: Find duplicate items in Collection
Hi,
Thanks for the update. I have implemented the IUserView on the form.
public partial class FrmUserRegistration : Form, IUserView { UserPresenter Presenter; public FrmUserRegistration() { InitializeComponent(); Presenter = new UserPresenter(this); } #region IUserView Members public string UserName { get { return txtUserName.Text; } set { txtUserName.Text = value; } } public string UserCode { get { return txtUserCode.Text; } set { txtUserCode.Text = value; } } public string UserPassword { get { return txtUserPassword.Text; } set { txtUserPassword.Text = value; } } public UserPersonalCollection Users { get { return grdUser.DataSource as UserPersonalCollection; } set { grdUser.DataSource = null; grdUser.DataSource = value; } } public event EventHandler AddUser; public event EventHandler LoadUser; #endregion private void btnAddUser_Click(object sender, EventArgs e) { if (AddUser != null) AddUser(sender, e); } private void FrmUserRegistration_Load(object sender, EventArgs e) { if (LoadUser != null) LoadUser(sender, e); } }
Thanks in advance
Shashi
New Post: Can not find SetCollectionValidator Extention Method
It's an extension method, so make sure you have the FluentValidation
namespace imported.
Jeremy
New Post: NullReferenceException using FluentValidation in MVC3
It has been almost two weeks since I sent a sample project and I have not heard from anyone regarding this issue. Are you able to reproduce the problem using the project I sent? If so, is this a problem with my understanding of FV or is this a bug?
I need to receive feedback as I wanted to make a presentation to our IT team about using FV as our standard validation tool. I am currently working on a WPF application requiring validation and have found examples integrating FV with WPF and IDataError. However, I cannot move forward until I have a satisfactory response regarding custom validation.
New Post: NullReferenceException using FluentValidation in MVC3
Hi
I never received the sample project. If you could send it again, I'll take a look at it when I get some time, although I can't promise when this will be.
Jeremy
Created Issue: Validation rules are not triggered on entering data [7117]
this is my code I have setup:
public class ReleaseViewModelValidator : AbstractValidator<ReleaseViewModel>
{
public ReleaseViewModelValidator()
{
RuleFor(r => r.Name).NotEmpty().Length(1, 30).WithMessage("Name must not be longer than 30 chars.");
}
}
[FluentValidation.Attributes.Validator(typeof(ReleaseViewModel))]
public class ReleaseViewModel
{
public int ReleaseId { get; set; }
[Remote("ReleaseExists", "Release", ErrorMessage = "This name already exists.")]
public string Name { get; set; }
public DateTime CreatedAt { get; set; }
}
GlOBAL.ASAX:
FluentValidationModelValidatorProvider.Configure();
VIEW:
model ILMD.Web.Models.ReleaseViewModel
@* Remote Validation*@
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm("Create", "Release"))
{
<p class="editor-label">@Html.LabelFor(model => model.Name)</p>
<p class="editor-field">@Html.EditorFor(model => model.Name)</p>
<p class="editor-field">@Html.ValidationMessageFor(model => model.Name)</p>
}
All my unit tests for the ReleaseViewModelValidator show green light. Fine.
But less cool is that entering some live data like 31 or entering nothing I do not see any client side error message.
Do I still have to include something in my partial view? The ModelState is also not correct, thus I am updating my database with null values....crash...bom...bang...
Can you help me please?
Edited Issue: Validation rules are not triggered [7117]
this is my code I have setup:
public class ReleaseViewModelValidator : AbstractValidator<ReleaseViewModel>
{
public ReleaseViewModelValidator()
{
RuleFor(r => r.Name).NotEmpty().Length(1, 30).WithMessage("Name must not be longer than 30 chars.");
}
}
[FluentValidation.Attributes.Validator(typeof(ReleaseViewModel))]
public class ReleaseViewModel
{
public int ReleaseId { get; set; }
[Remote("ReleaseExists", "Release", ErrorMessage = "This name already exists.")]
public string Name { get; set; }
public DateTime CreatedAt { get; set; }
}
GlOBAL.ASAX:
FluentValidationModelValidatorProvider.Configure();
VIEW:
model ILMD.Web.Models.ReleaseViewModel
@* Remote Validation*@
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm("Create", "Release"))
{
<p class="editor-label">@Html.LabelFor(model => model.Name)</p>
<p class="editor-field">@Html.EditorFor(model => model.Name)</p>
<p class="editor-field">@Html.ValidationMessageFor(model => model.Name)</p>
}
All my unit tests for the ReleaseViewModelValidator show green light. Fine.
But less cool is that entering some live data like 31 or entering nothing I do not see any client side error message.
Do I still have to include something in my partial view? The ModelState is also not correct, thus I am updating my database with null values....crash...bom...bang...
Can you help me please?