Reputation: 5407
First of all, I have to say that I understand how Data Annotation -based Model Validation works in ASP.NET MVC4 and I have it successfully implemented with DataAnnotationsModelValidatorProvider
. So I don't need assistance on setting it up.
But when it comes down to HtmlHelpers
, I'm struggling with trying to figure the context of the error message. And by saying context
, I mean which error we're talking about. Which Attribute returned the error?
What I can get, is the Key
for the error and the current ErrorMessage
but programmatically, there's nothing, that at least I'm aware of, that would communicate which error we're talking about. Whether it was Required
attribute or some other attribute, there's not way that I can find how to distinguish them.
Let's open the scenario a little bit. I have custom HtmlHelpers
to render ContentEditable
elements. For example Html.ContentEditableValidationMessageFor(m => m.firstName);
. It will output something like this:
<span contenteditable="true" data-valmsg-for="firstName" data-valmsg-replace="Please provide first name" class="field-validation-error">Please provide first name</span>
Now, I do have a jQuery plugin to handle and persist the changes in the contenteditable
element and it will persist them into the backend. However, the UI has nothing that would say which error message we're talking about. Humans can easily see it's the RequiredAttribute
, but programmatically there's no data to differentiate it from some MinLengthAttribute
for example.
In this scenario, if I would simply use the data-valmsg-for="firstName"
as the key for the localization, that'd return the same error message for all the errors concerning the same property.
To Round it Up
What would be the Best Practise, when ModelState
is available, to emit a unique ID for ModelError? Considering I'm using ASP.NET MVC4 and DataAnnotationsModelValidatorProvider
.
I can think of tons of ways to "Hack it Together" but I would like to use the ModelState
and whatever MVC provides. If it all goes down to writing a custom ModelValidatorProvider
, then I'm all open for it. As long as it is the best and most sustainable way of going about it. I'm all for Doing More Now and Less Later than Hacking it Now and Hacking it Forever to Keep It Working
Upvotes: 4
Views: 1164
Reputation: 2590
Even implementing ModelValidatorProvider
will not help, it is just a mechanism to provide ModelValidator
s based on Model Metadata. When during model binding process in a controller action ModelValidator
s are being invoked the result is just ModelValidationResult
which only contains MemberName
and a text Message
.
I think there is a dirty way to find out which ModelValidator is failed by checking the error message like this:
var modelErrors = ModelState.Where(m => m.Value.Errors.Count > 0).Select(m => new { Name=m.Key , Errors=m.Value.Errors});
by checking ErrorMessage of Errors for each key in modelErrors against ValidatorProvider error messages you can find out the error belongs to which Validator.
Upvotes: 2
Reputation: 1722
Can you give some context around the need to know which rule triggered the validation error, could it be a case of you trying to do something you shouldn't have too?
In general I use FluentValidation (http://fluentvalidation.codeplex.com/wikipage?title=mvc) in place of Data Annotation validation for many reasons, de-cluttering models, unit testing validation logic, allowing vastly more complex validation that include business logic. If your free to use 3rd party libraries I'd give it a look as it has always solved any validation problems I've had in the past.
It lets you write c# code that deals with your model validation via a fluent API. It has an MVC extension that wires everything up for you so other than creating the models validation class there is little impact from then on. An example for your code snippet above would be...
RuleFor(modelname => modelname.FirstName).NotEmpty().WithMessage("lease provide first name");
Upvotes: 4