Say I have a model property like this:
[Range(1, 31, ErrorMessage = "O dia de fechamento deve possuir valores entre 1 e 31")]
public int DataInicial { get; set; }
Even with a custom error message set on the annotation, I'm still getting the default error message for the Range annotation "Please enter a value less than or equal to 31.", when I type something like "32" or more at the #Html.TextBoxFor(model => model.DataInicial) field.
I'm aware of this post, but I think if you can set custom messages at annotation level, It should work without setting an App_GlobalResources and a .resx file, setting third-party libraries or whatever... I know that adding a .resx file and put all those validation strings there, is a "best-practice", but...
So, where I could be wrong, since the messages are not showing correctly?
Thank you in advance.
I was running into the same issue and experimented a little. Just learning MVC myself and it wasn't too obvious, but the solution seems nice and makes sense. The issue just comes down to which validation attribute gets triggered.
I found ErrorMessage is specific to the validation it is associated with.
A simple example should make it real clear...
[Required(ErrorMessage="xxx may not be blank.")]
[Range(0.0,1000.0,ErrorMessage="The value entered must be 0 to 1000.00")]
public virtual double xxx () // snip...
If empty, upon validation you will get "xxx may not be blank". While a value has been entered but not valid you should see the other error "The value entered...".
Related
So, I have one view with a textbox in it and I am trying to manipulate the error message when user does not put any value in that text field in my ASP.Net MVC 5 project.
Below is the model
[Display(Name = "Enter verification token sent to your email"), Required]
public string Token{ get; set; }
Now the problem is when user does not put any value I get below message in my screen
The Enter Verification Token sent to your email field is required.
Now as you can see the error message is taking it's text from the Display attribute of the property of the corresponding Model. But the error message is lengthy and confusing. Honestly, it does not make proper sense too. How to manage these situations. I am a beginner so I do not know many nuances of it but how experienced developer manage error message. Can we have a lengthy Display attribute and still tell ModelState validation to show a different short error message. Do, I need to manually add ModelState.AddModelError, or I am thinking too much?
How about displaying an error message as "Token field is required"
an we have a lengthy Display attribute and still tell ModelState validation to show a different short error message.
Yes. By using ErrorMessage property available on your Required attribute like this:
[Display(Name = "Enter verification token sent to your email"),
Required(ErrorMessage="Token field is required")]
public string Token{ get; set; }
Do, I need to manually add ModelState.AddModelError, or I am thinking
too much?
No you don't need it. It is too much.
I am working on a MVC 4 project. I am having an issue with multiple custom validation attribute on single property. Suppose I have 3 custom validation attribute for single property such as:
public class Test
{
[customAttribute1]
[customAttribute2]
[customAttribute3]
public string property1 { get; set; }
}
Currently when I post he form than all three custom validations are performed on the property (no matter whether first validation pass or fail).
What I want is if customAttribute1 validation fails than no need to validate the property with next next custom attribute. How can i achieve this?
The point of this behaviour is to return back (to the UI) all the errors in the Model, so the user can fix all the errors at the same time...
Let's say you want you password to be minimum 8 chars and have at least an uppercase and a number. The way you want your validation to run is to stop if the password is not long enough without checking the rest. Typical use case scenario:
User sets password "foo" -> submit
error - Password too short
User sets it to "foofoofoo"
error - Password must have an uppercase
User sets it to "FooFooFoo"
error - Password must have a number
User goes away frustrated...
So, if the 3 attributes are to be validated together, my suggestion is to keep this behaviour. If the 3 are exclusive then do as others suggested and combine them into a single attribute.
Ordering or executing conditionally is not supported AFAIK.
The best bet is to have all these 3 validations in the same attribute.
If you are badly in need of this kind of validation, then Fluent Validation can do it for you.
In my model I have a particular field that is annotated in the following manner:
[DataType(System.ComponentModel.DataAnnotations.DataType.Text)]
[RegularExpression("[0-9]{1,10}", ErrorMessage = "The stated Attempt Id is invalid!")]
public long? AttemptId { get; set; }
When I enter incorrect data in the Attempt ID it is giving me the following error message in the Model State:
The value 'cbcbxcb' is not valid for AttemptId.
I have other field with similar error messages but they're of type string instead of long? and the correct error message is being displayed in those cases when an invalid value is given. Why isn't the message for the 'long?' being used? I'm displaying my errors using the folowing literal tag in the page.
<%: Html.TValidationSummary() %>
EDIT: I have attempted to change the validation in the model to the following:
[Required(ErrorMessage="The stated Attempt Id is invalid!", AllowEmptyStrings=true)]
This however is still incorrect. Firstly, I need to allow the field to be left empty, and when I do it's giving me the 'The stated Attempt Id is invalid!' error message. Secondly when I do enter invalid data in the field it's reverting back to its old bad error message.
The RegularExpression validation attribute only works with string types. To get a custom error message, use the Required validation attribute instead and put your own custom error message in.
If your model parameter isn't mandatory, you could perform the validation within the controller and add your own custom message using the ModelState.AddModelError method - this is a bit of a hack, though.
its probably the fact that MVCs binding can't even cast the input value into the correct type, so it already knows the value must be invalid.
You should be using FluentValidation
The built in validation stuff using attributes is brittle and nasty - to say the least.
A forewarning: I've relatively new to MVC and its paradigm and to some of its inner workings, but I'm pretty comfortable with it. This is my second ground-up MVC application and I'm a little stumped with how to solve a "problem" one of our testers found.
What the users get is an edit screen given an effective date for daily LIBOR rates that come from Treasury (percentages). The rates are always between 0 and 100 and consequently I've tried to constrain that range using a RangeAttribute in the metadata for one of my domain objects. I've specified the range like so:
[Required, DisplayName("Published Rate"), Range(typeof(decimal), "0", "100")]
public object PublishedRate { get; set; }
Notice that I'm passing in string values as the RangeAttribute does not have an overloaded constructor that takes decimals. This seem to work great until a user goes and enters something out of the ordinary, like:
"0.000000000000000000000000000000001"
This causes UpdateModel() to fail; the ModelState shows this error (three times for the same ModelState value, curiously):
The parameter conversion from type 'System.String' to type 'System.Decimal' failed.
Digging into the errors reveals the cause. The first line below is what's reported by the validation for the field. I found it curious that this did not bubble up to the model validation errors (i.e. did not show up in the summary validation list for the model):
"0.000000000000000000000000000000001 is not a valid value for Decimal."
"Value was either too large or too small for a Decimal."
System.Web.Mvc.ValueProviderResult.ConvertSimpleType() and System.ComponentModel.BaseNumberConverter.ConvertFrom() are throwing the exceptions.
A user is never going to enter a value such as this, but I wouldn't mind knowing if there are any mechanisms built in to MVC that could or will prevent this (server-side, that is). There doesn't seem to be an issue with numbers like the following, it only seems to break with ones that are very small.
"0.555555555555555555555555555555555"
At the end of the day I really only need 9 digits of precision. The database table column backing these values is a decimal(9,6). I know I could implement a custom model binder for my model and manually collect the values from the Request, but there's got to be something a little easier, such as a custom FilterAttribute or something that can correct the value before its attempted to be bound to the model, I'm just not sure what, and am looking for suggestions.
I seem to recall reading about some issues with trying to constrain decimal values using a RangeAttribute but I can't recall the issue. Perhaps you MVC gurus out there can shed some light on the situation.
You could use a Regex attribute to contain the decimal to a precision of 9. This would also allow you to add a custom message when the Regex fails, such as "Your value may have a maximum of 9 places after the decimal." or something similar. Also if you have client side validation enabled, the Regex will work in both client and server side validation.
So after a couple of hours of head banging I settled on the following custom model binder for decimals. It makes sure that all decimal values are parseable before binding them.
public class TreasuryIndexRateDecimalBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var providerResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (providerResult != null)
{
decimal value;
if (!decimal.TryParse(providerResult.AttemptedValue, NumberStyles.Float, CultureInfo.CurrentCulture, out value))
{
// TODO: Decide whether to show an error
// bindingContext.ModelState.AddModelError(bindingContext.ModelName, "error message");
return 0m;
}
return Math.Round(value, 6);
}
return base.BindModel(controllerContext, bindingContext);
}
}
The binding is set up in Application_Start() to register it for all decimal values.
protected void Application_Start()
{
ModelBinders.Binders.Add(typeof(decimal), new TreasuryIndexRateDecimalBinder());
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
Unless somebody comes along with a more interesting approach I think I'll stick with this.
I am using asp.net mvc 3 and I keep getting the following error.
Validation type names in unobtrusive
client validation rules must be
unique. The following validation type
was seen more than once: number
I have no clue as I have this
#Html.TextBoxFor(x => x.Mark)
// my viewmodel
[Required(ErrorMessage = "Message")]
[Number(ErrorMessage = "Message")]
public decimal Mark { get; set; }
If I change it from a decimal to string it will not complain. What is going on?
Edit
I think it is because of this the [Number(ErrorMessage = "Message")] annotation. I am using this library Data annotation extensions
It seems not not like that I am using decimals. Anyone know why?
If you are using type decimal, you do not need to use the [Numeric] attribute because MVC already sees you are using a numeric type and injects that in for you (which is causing the error). When you change to a string, the [Numeric] is then needed to tell the validation how you want that string to work.
In the next version of DataAnnotationsExtensions, I'll change the [Numeric] attribute so it won't collide with the MVC version in this case. But for now, removing the [Numeric] attribute will be just fine because [Numeric] on a numeric type is redundant anyway.
You probably have multiple model validators which are adding the same client rule twice, are you using a custom validatiOn provider?
Required will become duplicate since Mark is not nullable. I would change it to be decimal?