I've got FluentValidation set up in my ASP.Net MVC 3 project. I have a form which has two inputs. Either can be blank, but not both.
Here's what I have:
RuleFor(x => x.username)
.NotEmpty()
.When(x => string.IsNullOrEmpty(x.email) == true)
.WithMessage("Please enter either a username or email address")
This correctly puts the error directly above my username field. However, when both fields are left blank I'd prefer the Validation Summary to show the message
Is there a way to do this? I've been thinking I could create an unused field in the model and put the error on that (if the other two are blank),
RuleFor(x => x.unused_field)
.NotEmpty()
.When(x => string.IsNullOrEmpty(x.email) == true && string.IsNullOrEmpty(x.username) == true)
.WithMessage("Please enter either a username or email address")
but this feels like an awkward way to do it. Is there a way I can just add a message to the validation summary?
The only reference I could find was this.
Now if your model is that simple and this rule is the only one then this rule should be enough:
RuleFor(x => x)
.Must(x => !string.IsNullOrWhiteSpace(x.Email) || !string.IsNullOrWhiteSpace(x.UserName))
.WithName(".") // This adds error message to MVC validation summary
.WithMessage("Please enter either a username or email address");
Just add @Html.ValidationSummary()
to your view and you're good to go.
But if you're going to put more rules on your model then to my knowledge there is only one 'hacky' way I could think of:
in your controller action add this:
if (!ModelState.IsValid)
{
if (ModelState["."].Errors.Any())
{
ModelState.AddModelError(string.Empty, ModelState["."].Errors.First().ErrorMessage);
}
// ...
}
This will add first error message from "."
property to model property (adapt it to your needs). Also you will have to do a @Html.ValidationSummary(true)
to show only model level errors in validation summary.
Third option: add rule(s) to unused_property
and use @Html.ValidationSummaryFor(x => x.unused_property)
as a validation summary
Your issue can be solved with FluentValidation AbstractValidator.Custom:
Custom(m => String.IsNullOrEmpty(m.Username) && String.IsNullOrEmpty(m.Email)
? new ValidationFailure("", "Enter either a username or email address.")
: null);
Empty string in ValidationFailure constructor assures validation message is not bound to any input field so it appears in validation summary like
ModelState.AddModelError("", "Enter either a username or email address.")
would.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With