Why is MVC 3 Validation overwriting mine? - c#

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.

Related

Validation error message displays the entire text of the property in Asp.Net MVC 5

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.

ActionFilterAttribute - A potentially dangerous Request.Form value

I have an auditing system in place that is failing when form values contain HTML.
I have added the [AllowHtml] attribute to the model property in question, and have tried adding [ValidateInput(false)] to the controller action, as well as using the Unvalidated() extension method on HttpRequestBase.
None of this is preventing the error. The line of code it fails on (in the auditing code, OnActionExecuting() of the derived ActionFilterAttribute) is:
return Json.Encode(new { request.Cookies, request.Headers, request.Files, request.Form, request.QueryString, request.Params });
Error is:
A first chance exception of type
'System.Web.HttpRequestValidationException' occurred in System.Web.dll
Additional information: A potentially dangerous Request.Form value was
detected from the client (Note="<p>test</p>").
"Note" being the model property with [AllowHtml] on it.
Any ideas on how I can prevent this?
It's important to understand the order of operations in the ASP.NET MVC pipeline. Your OnActionExecuting method gets called before the action in your controller even begins. If your controller action hasn't executed, that means your ValidateInput annotation isn't being considered. It also means the model binding hasn't taken place, so your AllowHtml annotation isn't considered. At this point, you've just got access to the basic Form collection, and when you try to access the data by serializing via Json.Encode() the security protection of ASP.NET is still kicking in.
To solve the issue you could either disable request validation entirely in the Web.config (not recommended), or give your JSON serialization more attention. To do so, you will have to call Unvalidated() when unwrapping the value of the property:
return Json.Encode(new {
request.Cookies,
request.Headers,
request.Files,
new {
Note = Request.Unvalidated().Form["Note"]
//Add any other properties you care about here
},
request.Form,
request.QueryString,
request.Params
});

ASP.NET MVC - Default Range validation error message not being overridden

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...".

Unobstructive client validation error

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?

ModelState.AddModelError showing error twice

With MVC stuff when there is an error on property level, we can add error to ModelState
but the same error is added to the summary also. How can we avoid to display it twice.
I want to display only public errors in the message summary and all other at property level.
Regards
Parminder
When defining your validation summary set the first parameter to true which means Exclude Property Errors.
Eg:
<%= Html.ValidationSummary(true, "Unable to save item. Please correct the errors and try again.")%>
From MSDN:
excludePropertyErrors Type: System.Boolean
true to have the summary display model-level errors only, or false to have the summary display all errors.

Categories

Resources