MVC Datatype ErrorMessage - asp.net-mvc

DataType ErrorMessage doesn't work.
MVC4 DataType ErrorMessage doesn't seem to work.
I have this dataannotation Attribute:
[DataType(DataType.DateTime, ErrorMessage = "Invalid date")]
public override DateTime? BirthDate { get; set; }
but client validation return this error:
The field BirthDate must be a date.
this is the Html portion:
<input Value="" class="date" data-val="true" data-val-date="The field BirthDate must be a date." data-val-required="El campo Fecha nacimiento es obligatorio" id="Patient_BirthDate" name="Patient.BirthDate" type="text" value="" />
Any idea?

On MVC 4 I was able to change the error message in the View with Html.ValidationMessageFor.
See an example:#Html.ValidationMessageFor(model => model.FechaDesde, "Fecha Inválida")

Short Answer: Purpose of DataType.DateTime is NOT to validate your DateTime entry for Birthday property. This is the reason. What it does is just formats the DateTime before displaying it on your view.
What you need is to have [Required] attribute on top of that as well.
However, what i usually prefer to use is Jquery Datepicker and it doesn't even allow user to enter any text, but a valid date.
Edit: When you decorate a model property with [DataType(DataType.Date)] the default template in ASP.NET MVC 4 generates an input field of type="date". Browsers that support HTML5 such Google Chrome render this input field with a date picker.
You may enforce this with code:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? BirthDate { get; set; }
In order to correctly display the date, the value must be formatted as 2012-09-28

Related

Why validation is not working with Html.TextBoxFor but is when using Html.EditorFor?

I am trying MVC's datatype attributes, and just created a simple scenario like the following:
The View:
#model MVC4.Models.Model
#{
ViewBag.Title = "DataTypeAttribute";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<h2>DataTypeAttribute</h2>
#using (Html.BeginForm("SubmitData", "Home"))
{
<div>
#Html.ValidationSummary()
</div>
#Html.EditorFor(m => m.Email)
<br />
<br />
#Html.EditorFor(m => m.PostalCode)
<br />
<br />
#Html.EditorFor(m => m.TextOnly)
<br />
<br />
<button type="submit">Submit</button>
}
The Model:
public class Model
{
[DataType(DataType.EmailAddress)]
[Required]
//[EmailAddress]
public string Email { get; set; }
[DataType(DataType.PostalCode)]
public string PostalCode { get; set; }
public string TextOnly { get; set; }
}
"SubmitData" is just a controller that, returns View(..., model) if ModelState.IsValid is false.
Although posts like this do a good job in tackling the differences between Html.TextBoxFor and Html.EditorFor, I could not find an answer as to why validation for the datatype EmailAddress will not work when using TextBoxFor. I did find people mentioning TextBoxFor does not take metadata into account, while EditorFor does.
But does this make sense ? So TextBoxFor does not offer support for client validations ?!
I wonder what is the reason for the difference between the two ?
TextBoxFor() does work with validations.
[DataType(DataType.EmailAddress)] is not a validation attribute. Its an attribute that determines the type of input to display by setting the type attribute in the rendered html. For example <input type="text" ..>, <input type="date" ..>, <input type="email" ..> in order to render the browsers implementation of a HTML4 datepicker, email input etc.. It works only for EditorFor() because TextBoxFor() as its name suggest generates and input with type="text"
If you want validation for an email address, then you use the [EmailAddress] attribute on your property.
[Required]
[EmailAddress]
public string Email { get; set; }
Edit (further to the comments)
One of the features of HTML5 is the ability to validate user data without relying on scripts. One such form of browser validation is using the type attribute. The use of [DataType(DataType.EmailAddress)] on a property that is rendered with #Html.EditorFor() adds type="email" to the input element. From the MDN documentation
email: The element represents one email address. Line breaks are automatically stripped from the input value. An invalid email address can be set, but the input field will only satisfy its constraints if the email address satisfies the ABNF production 1*( atext / "." ) "#" ldh-str 1*( "." ldh-str ) where atext is defined in RFC 5322 section 3.2.3, and ldh-str is defined in RFC 1034 section 3.5.
If your are currently seeing a validation error message associated with the property, and you have not added the [EmailAddress] attribute, then it means that jquery.validate.js is not loaded and you are seeing the browsers error message associated with type="email".
When jquery.validate.js is loaded (correctly), the novalidate="novalidate" attribute is added to the form element, which specifies that form is not to be validated (using the HTML5 validation) when submitted. The relevant code from jquery.validate.js is (approx line 35)
// Add novalidate tag if HTML5.
this.attr('novalidate', 'novalidate');
This is added to prevent possible confusion between error messages displayed by browser validation and jquery unobtrusive validation.
As to why DataTypeAttribute attribute inherits ValidationAttribute when it does not actually do validation, from Brad Wilson himself in this answer
The reason it derives from ValidationAttribute is so that you could create a new custom data type class, which was both a DataType and a Validation, all wrapped up into one. It's an unfortunate side-effect of .NET not allowing multiple inheritance.

data-val-date attribute added to dateTimePicker even without ValidationAttribute in model

I emit a datetimepicker with this line
#Html.EditorFor(model => model.Event.EventStart)
My editor template is like this:
#model DateTime?
#Html.TextBox("", string.Format("{0:yyyy-MM-dd HH:mm}",
Model.HasValue ? Model : null), new { #class = "dateTimePicker" })
and that will result in the following html:
<input type="text" value="2013-10-26 00:00" name="Event.EventStart"
id="Event_EventStart" data-val-required="The Startdatum field is required."
data-val-date="The field Startdatum must be a date." data-val="true"
class="dateTimePicker hasDatepicker input-validation-error">
That is also the case if I do not have a #Html.ValidationMessageFor(model => model.Event.EventStart) line.
There is nothing in my code that should enable validation for the property EventStart.
In my model it only looks like this:
[Display(Name = "Startdatum")]
public DateTime EventStart { get; set; }
It seems like jquery ui (most suspect) is adding validation for dates to my dateTimePicker.
Why?
Or is the presence of the data-val-date attribute also triggering datetime validation?
The validation fails:
The field Startdatum must be a date.
It would be nice to either be able to disable the validation or add validation for datetimes instead of dates.
Is there some way to actually have the responsibility to add validation myself with data annotations as I do usually (with other datatypes)?

Validation error - The field Int32 must be a number - on string property

I have a funny problem and I did not find the cause.
In asp.net MVC application I have a form that saves some simple information. All fields can be stored neatly except one. This field (string) returns validation error "The Int32 field must be a number" but only if the sentences in the text contains a single digit number. For example, if the sentence is as follows:
"Some simple sentence that contains the number 3" I'll get a validation error - "The Int32 field must be a number", if that same sentence transformed into:
"Some simple sentence that contains the number 30" or "Some simple sentence that contains a 30%" - no errors
Field property from a model:
[Display(Name = "Some name")]
[StringLength(500, ErrorMessage = "You can enter up to 500 characters.")]
public string Akcija { get; set; }
Next to that field I have one (string) field with the same property characteristics, and it is working properly.
Clip from view:
<div>
#Html.TextAreaFor(m => m.Akcija, new { style = "width:500px; height:100px;" })
#Html.ValidationMessageFor(m => m.Akcija)
</div>
It can not be simpler than that, but the problem is around here.
Do you have any suggestions?
Edit:
If I keep trying to save the changes it will be saved to the database regardless of the validation error. It seems to me that this is a JavaScript validation error or a bug
Edit 2 - Generated HTML:
<textarea cols="20" data-val="true" data-val-number="The field Int32 must be a number." data-val-required="The Int32 field is required." id="Akcija" name="Akcija" rows="2" style="width:500px; height:100px;">
Web aplikacije i siteovi 3 sa 30% sniženja
I do not know where it comes from - this attribute "data-val-number =" The field Int32 must be a number. '" And " data-val-required = "The Int32 field is required.'"
I'm not in the code imposed these rules
Try tagging the property with [DataType(DataType.MultilineText)]. Maybe that will make it explicit to the TextAreaFor helper.
If anyone ever run into this problem, the workaround is to use Html.EditorFor how it follows:
First: Add validation attribute [DataType (DataType.MultilineText)] to model property
so that model property looks like this:
[Display(Name = "Some name")]
[StringLength(500, ErrorMessage = "You can enter up to 500 characters.")]
[DataType(DataType.MultilineText)]
public string Akcija { get; set; }
Secondly: Make Template for Html.EditorFor.
Template create in a folder Views/Shared/EditorTemplates - if there is no folder EditorTemplates, make it.
In the folder EditorTemplates create a partial view named with the name of the model property.
In my case it is: akcija.cshtml
In this view should be forwarded the value of the model property and you must include the HTML that defines the field of view so that the template, in my case, look like this:
#model System.String
#if(!string.IsNullOrEmpty(Model))
{
<textarea name="Akcija" style="width:500px;height:100px;">#Model.ToString() </textarea>
}
else
{
<textarea name="Akcija" style="width:500px;height:100px;">#Model</textarea>
}
Third In your View change Html.TextAreaFor in Html.EditorFor and put a reference to your template. Html.EditorFor, in my case, now looks like this:
<div>
#Html.EditorFor(m => m.Akcija, "akcija")
#Html.ValidationMessageFor(m => m.Akcija)
</div>
And that's it, problem solved.
Note: When naming template and objects within the template and the template it self, note the naming convention. Note that my template is named with small letter and in html template there is no id attribute for html object.
I hope that this will help someone
Use a nullable int/Int32.
public int? mobilequantity { get; set; }
or
public Int32? mobilequantity {get; set;}
that works on my form

mvc [DataType(DataType.EmailAddress) no validation

I'm using this code on an email field:
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[DataType(DataType.EmailAddress)] does not work (validation does not occur no at a server not on the client side).
I am not sure if I should implement myself a Custom Attribute or I can use one included with MVC 3.
Could you please suggest me a solution for creating a custom attribute in case I need to.
I read also about some additional extensions, example
http://nuget.org/packages/DataAnnotationsExtensions.MVC3
Would you suggest it to me?
You could use the usual DataAnnotations library by just using [EmailAddress]
using System.ComponentModel.DataAnnotations;
[Required]
[EmailAddress]
public String Email { get; set; }
Also just for reference, here's the regular expression version of this validation:
[RegularExpression(#"^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)#([A-Za-z0-9]+)(([\.\-‌​]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$", ErrorMessage = "Email is not valid")]
public String Email {get; set;}
Best of luck!
At the moment I have solved my problem using
DataAnnotationsExtensions
it just works, you add their library with NuGet
using DataAnnotationsExtensions;
[Required]
[DataType(DataType.EmailAddress)]
[Email]
public string Email { get; set; }
It looks like all the answers focus on the Data Model while this issue can be affected by the View itself.
The following on MVC .NET 4.5 is working alright:
Data model:
[Required]
[DataType(DataType.EmailAddress)]
[DisplayName("Email")]
public string Email { get; set; }
Razor View:
#Html.LabelFor(model => model.Email)
#Html.EditorFor(model => model.Email)
Note: do not need to add [EmailAddress] attribute. If you use [DataType(DataType.EmailAddress)] along with #Html.EditorFor() in your View, you should be fine.
As highlighted with rich.okelly, at the end you want your input rendered as <input type="email" />.
May be this will be helpful for someone. Following works for me
[Required(ErrorMessage = "*")]
[DataType(DataType.EmailAddress)]
[EmailAddress]
public string Email { get; set; }
But does not work following
[Required(ErrorMessage = "*")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
I am using MVC 5 & .NET 4.5
As Felix mentioned, the problem is on the View level, you need to use EditorFor() in your View instead of TextBoxFor(), the EditorFor() will render:
<input type="email" />
which will trigger the validation, while TextBoxFor() will render:
<input type="text" />
So in order to validate your entered email address, you need (in combination with EditorFor()) to use only:
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
This way, your entered value for email will be always validated, but if you don't enter a value for email, nothing will happen (unless you specified the [Required] attribute), the form will be submitted with an empty email address.
[DataType(DataType.EmailAddress)] can't recognize # and [EmailAddress] can't recognize .com , so use RegularExpression :
[RegularExpression(#"^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)#([A-Za-z0-9]+)(([\.\-‌​]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$", ErrorMessage = "Email is not valid")]

how to show some text in html.LabelFor?

I am doing int like this:
Hello <%= Html.LabelFor(user => user.UserName)%>
But iam getting not a value which is in Property but something strange like this:
Hello User Name,
How can do it to give some value in label out?
Add DataAnnotations to your model/viewmodel:
public class Customer
{
[Display(Name = "Email Address", Description = "An email address is needed to provide notifications about the order.")]
public string EmailAddress { get; set; }
[Display(ResourceType=typeof(DisplayResources), Name="LName", Description="LNameDescription")]
public string LastName { get; set; }
}
Source: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute(v=VS.95).aspx
If you don't provide a display name by the DisplayAttribute then Html.EditorFor(...) uses the properties name, spliting it on upper case letters:
PropertyName --> Label text
Email --> Email
EmailAdress --> Email Address
The reason for this is because Html.LabelFor will do just that - create a label for the property. In this case, it is producing a label of 'User Name' since the property name is UserName.
You just need to look at the model (or whatever your passing to the view) to return the property value: Html.Encode(Model.UserName)
Update (since this was nearly 3 years ago but people have recently upvoted):
You can just use <%: Model.UserName %> to get the HTML encoded value (<%= writes it as raw and <%: writes it encoded).
If you're using a Razor view engine, then #Model.Username will write it out already encoded.

Resources