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
Related
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
I am a newbie in ASP.NET MVC, and something made me confused.
I am creating a login/registration web-app, and when I came to confirm password, I was a bit confused. I surely don't want confirm password column in my database. So for that reason, I use ViewModel. And I use data annotations for validation in my ViewModel. So there is no need to write any validation code in my Domain Model.
But when Entity Framework creates a table from my Domain Model object, from where will it get information for example about how many characters should username take? If I used data annotations in my domain model, I would write MaxLength or something.
Should I validate data in domain model too?
You client side validation can be taken care of using Data Annotations on your View Model and include jQuery validation script in your View.
So in your View Model, you can set minimum password length restriction like this:
using System.ComponentModel.DataAnnotations;
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[System.ComponentModel.DataAnnotations.Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
Of course, this is only for client side validation, for server side validation, you have to validate the data in your controller, but i don't believe you have to use data annotation on your domain model.
So in your controller, you can validate the data passed through like this
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterViewModel model)
{
//checks for data passed through, if somehow people bypasses client side validation
if (ModelState.IsValid)
{
//continue
}
//validation failed, return to view
return View(model);
}
ModelState.IsValid indicates if it was possible to bind the incoming values from the request to the model correctly and whether any explicitly specified validation rules were broken during the model binding process. ---- what does this do : ModelState.IsValid
I have properties declared in my view model like:
[Required(ErrorMessage = "The Date field is required for Start.")]
[Display(Name = "Start")]
public DateTime DateStart { get; set; }
However, I am still getting a default The Start field is required error message. I assume this is because a non-nullable DateTime is implicitly required, and the Required attribute is ignored. Is there a way to customise my error message for these specific properties, besides making them nullable?
You right, your problem is that your property is not nullable. For not nullable properties attribute Required is meaningless. When there is no StartDate value, validation is not go to your Required attribute and fails on previous step. If you want to get your ErrorMessage you should
use:
[Required(ErrorMessage = "The Date field is required for Start.")]
[Display(Name = "Start")]
public DateTime? DateStart { get; set; }
You cannot customize ErrorMessage for nonullable types that get null on modelbinding, cause it is hardcoded deep in MVC framework.
I've started with refresh new test project in MVC 4 and create a test model
public class TestModel {
[Required(ErrorMessage = "The Date field is required for Start.")]
[Display(Name = "Start")]
public DateTime DateStart { get; set; }
}
Then in my model I just have this:
#using(Html.BeginForm()){
#Html.ValidationMessageFor(a => a.DateStart);
#Html.TextBoxFor(a => a.DateStart)
<input type="submit" value="add"/>
}
When I remove clean the text box and hit submit, I am getting the customized error message instead of the default.
The Date field is required for Start.
This make sense to me, imagine if this is a multilingual application, you will definitely need to customize the error message for that country. It doesn't take a rocket scientist to realise the need for customized message. And I would expect MVC team have that covered.
I have my asp.net mvc 3 application with entity framework and i used the Database First model to set it up.
My Steps below:
1. Genarated a database with tables
2. Created ADO.NET Entity Data Model file (.edmx) and imported the tables
3. inside the design i added a Code Generation item and used ADO.NET DbContext Generator
4. a Model1.tt holder as been made with all of the tables Models
I have edited the models and updated them with DataAnnotations Attributes (just for the example a well known one)
public class LogOnModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
Now when im making changes to the database and updating it to the edmx file all the models will be overwritten and the DataAnnotations Attributes will disapear.
my question:
how can i use database first model and still edit the models for speciific validation like im free to do with code first model?
(please no third party tools solution)
thanks
You need to use buddy classes. See my dated but still useful article http://msdn.microsoft.com/en-us/library/ee256141(v=vs.98).aspx
Use ViewModels in your Views. This will decouple your EF entities from your UI logic.
I'm new to ASP.NET MVC, and I have this issue.
So, my model have a password attribute, when creating should be required, but when editing it should be optional, so you only change the password if you want to, but I don't know how to let it be optional if I mark it with required in the model. What should I do?
The best solution is to have a different view for changing the password?
I appreciate your help, thanks!
[Required]
[ValidatePasswordLength]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
Either create a separate view model, or in your controller code check if its there, if not use ModelState.AddError("fieldName", "PAssword is required")