Had a user include a "<" in their password. This of course isn't allowed and was causing a Post-Back crash. What threw me was "<" was allowed in other input boxes on my site.
Traced the problem down to the fact that it was because the Password box was being treated like a Password box using DataType.Password. If I commented out that DataType attribute, it works (but of course displays the password on the screen as I'm typing)
Doing some research and Testing, I found 2 possible solutions but I can't tell the difference between the two other than Method # 2 breaks the UI style and looks ugly
Method #1 ... Modify the Model...
[Required]
[Display(Name = "Password")]
[AllowHtml]
[DataType(DataType.Password)]
public string UserPassword { get; set; }
#Html.EditorFor(model => model.UserPassword ....
This option makes me nervous because I really don't want to allow HTML code in any of my inputs.
Method #2 ... Modify the View
[Required]
[Display(Name = "Password")]
public string UserPassword { get; set; }
#Html.PasswordFor(model => model.UserPassword ....
This makes me nervous because I'm relying on any views that display this model to have been done correctly and not present the password in plain text.
So my questions are:
Why does MVC\Razr seem to handle HTML just fine for a normal text box but chokes when you flag it as a Password DataType?
Which of the two methods is the Best practices and safest? (Is their a 3rd option?)
Thanks
In my Mvc5 test project I have a model with a property like the following:
[Required]
[DisplayName("Codigo Cliente")]
public int ClientCode{ get; set; }
the default error message when the user enteres a letter of special character in the editor is:
The field Codigo Cliente must be a number.
How can I modify this? in this case I need to change the language, but in case that I wanted to show a more specific error what can I do?
I have tried with the DataType attribute but the Enum does not have a value that applys for this case (numbers)
Use Range:
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.rangeattribute.aspx
Or use IntegerOnly from Data Annotations Extensions
http://dataannotationsextensions.org/Integer/Create
The simplest way I found to solve this issue is use String with Range attribute in Data Annotation Model like specify below.
[Required]
[Range(0, int.MaxValue, ErrorMessage = "Codigo Cliente must be a positive or negative non-decimal number.")]
[DisplayName("Codigo Cliente")]
public string ClientCode { get; set; }
In Range attribute you can specify your custom Error Message.
For Interger use int.MaxValue , For double use double.MaxValue like so on.
I hope this will help you a lot.
If you want to specify a message you must use this
[Required(ErrorMessage = "your message")]
If you want to use a lang. based message is not that easy. You can use multiple resource file (for every language you need) and try a custom error binder that extends the DefaultModelBinder and make an override of the method BindModel(), there you can make your custom validation ad use your custom language message.
I'm using DataAnotation for validation and i need disable it of in some cases.
F.E. on create i need user insert password and confirmation, but for edit it can stay empty and not changed.
I have this model:
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[DisplayName("Re-enter Password")]
[Compare("Password", ErrorMessage = "The password and confirmation do not match.")]
public string PasswordControl { get; set; }
Enought vould be disable required on password on edit.
AFAIK, there are two ways, either will work.
Use different model for edit and insert. I prefer and use this one in my application. It's easy and future proof(Edit and insert models and rules may be quite different).
Customize a ValidationAttribute and override IsValid method. Use some context such as IsEdit field of your model. It can be used since MVC3. See the "Model Validation Improvements" part of this article http://weblogs.asp.net/scottgu/archive/2010/07/27/introducing-asp-net-mvc-3-preview-1.aspx
my object has field with data type int. when i put in html form in this textbox letter not number the validator say- The field must be a number. how can i change this messages like this
[Required(ErrorMessage = "Введите название")]
[DisplayName("Название")]
public int age { get; set; }
I haven't found a clean way to achieve this using Data Annotations. One way would be to write a custom model binder but this seems like a lot of work to do for such a simple task.
Another way to achieve this is to add an App_GlobalResources folder to your ASP.NET application. Add a resource file called Messages.resx containing a PropertyValueRequired string resource.
PropertyValueRequired = "Some custom error message"
In your Application_Start register the resource class key:
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
DefaultModelBinder.ResourceClassKey = "Messages";
}
Note that ASP.NET MVC 2 uses the PropertyValueInvalid instead of PropertyValueRequired resource key.
IMO using Data Annotations to perform validation logic is limited (maybe in .NET 4 this will change). If you want to have full control over the validation logic I would recommend you using a validation library such as Fluent Validation or xVal.
I ran into the same problem and worked around it by specifying a RegularExpression that only allows positive natural numbers.
[Required(ErrorMessage = "Введите название")]
[DisplayName("Название")]
[RegularExpression(#"^[0-9]+$", ErrorMessage = "Поле возраст не является числом")]
public int age { get; set; }
Not sure if there are any downfalls to this solution. It seems to work fine for me.
PS: If you don't want to allow leading zeroes use "^[1-9]+[0-9]*$".
In retrospect: I have to admit though it's a bit weird to add a regular expression to an integer.
I'm working with the NerdDinner sample application and arrived at the section which deals with the Virtual Earth map. The application stores some values for the longitude and latitude. Unfortunately on my system floating point numbers are stored with a comma as the decimal separator, not a dot like in the US. So if I have a latitude of 47.64 it's retrieved and displayed as 47,64. Because that value is passed in a function call to the Virtual Earth API it fails at that point (e.g. JavaScript API expects 47.64, -122.13, but gets 47,64, -122,13).
I need to make sure that the application always uses dots. In a WebForms app I would have a common class which overrides the System.Web.UI.Page.InitializeCulture() method and I would be inheriting my pages from that class.
I am not sure about how to do the same with MVC. Do I need a customized ViewPage or something? Is there an easy way to solve this? Examples?
Because setting <globalization/> to en-US did not help at all I decided to create a custom class which initializes the proper culture settings and make sure that all views which require this behavior are inherited from my custom class.
NerdDinnerViewPage.cs:
using System.Globalization;
using System.Threading;
using System.Web.Mvc;
namespace NerdDinner.Views
{
public class NerdDinnerViewPage<T> : ViewPage<T> where T : class
{
protected override void InitializeCulture()
{
base.InitializeCulture();
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentCulture.Clone() as CultureInfo;
if (Thread.CurrentThread.CurrentCulture != null)
{
Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator = ".";
Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator = ".";
}
}
}
}
Edit.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="NerdDinner.Views.NerdDinnerViewPage<NerdDinner.Models.DinnerFormViewModel>" %>
I'm a Danish developer and was facing exactly the same problem. I found a working solution which has been kindly described by Kristof Neirynck on his dev blog:
Custom Model Binder
Best regards, Finn Vilsbaek
When you say
on my system floating point numbers are stored with a comma as the decimal separator
I assume you mean that they are formatted with a comma, floating point numbers are stored as float.
Whilst you can tackle the formatting issue by setting Cultures the "real" fix is to change the code. OK, it's not your code so maybe you don't want to do that on this occassion, but for general reference you need to ensure that when formatting floats or anything else you use the appropriate culture. In the case of fomatting a number for use by an API you would use the InvariantCulture.
I.e. use foo.ToString(CultureInfo.InvariantCulture) instead of foo.ToString() and likewise when using string.Format(...).
Edit I've just taken a look at the NerdDinner code and have realised that this error is in the Javascript not in C#, so my code above isn't going to help. I don't know if it is possible to format numbers in Javascript, but the real solution I think is to fix the model code to return a correctly formatted string.
Edit 2 I'd suggest you try the following:
In the SearchController.cs change the Latitude and Longitude in JsonDinner to strings. i.e.
public class JsonDinner {
public int DinnerID { get; set; }
public string Title { get; set; }
public string Latitude { get; set; }
public string Longitude { get; set; }
public string Description { get; set; }
public int RSVPCount { get; set; }
}
Then scroll down to the SearchByLocation method and change the Lat/Long lines to format the strings correctly for JavaScript:
Latitude = dinner.Latitude.ToString(CultureInfo.InvariantCulture),
Longitude = dinner.Longitude.ToString(CultureInfo.InvariantCulture),
This should mean that you do not need the fix you put in, and should fix your other question... where I will leave a comment. Hope this helps, I haven't fully tested is as I am not in your locale, but it certainly appears to work.
I'm using a simple quickfix in the TemplateEditor. My application is only using swedish (comma as decimal separator) so it's a single string.Replace but you could of course make it aware of multiple cultures.
In my Views/Shared/EditorTemplates/Decimal.ascx:
I fixed this on the JavaScript-side instead, making sure that what is passed in to the map-library is using points (.), and what is populated back into the text boxes are using commas (,). Obviously, this is not meant for localization, but a quick fix.
Map.js in callbackForLocation:
//If we've found exactly one place, that's our address.
if (points.length === 1) {
$("#Latitude").val(points[0].Latitude.toString().replace('.', ','));
$("#Longitude").val(points[0].Longitude.toString().replace('.', ','));
}
Map.ascx in the jquery-ready():
var latitude = <%=Model.Latitude.ToString().Replace(',', '.')%>;
var longitude = <%=Model.Longitude.ToString().Replace(',', '.')%>;