I have a model of name Student
public class Student
{
[Required]
public string Name { get; set; }
public string Number { get; set; }
public string Email { get; set; }
}
My question is that, does form is submitted and then validations are checked or there is another mechanism that post hidden form values to the server side validations ?
Generally in web development, validation occurs both client side and server side.
You want to scrub the forms for any unwanted data or characters before they are submitted, and you want to check them / scrub them again server side to ensure nothing is being passed that is unwanted.
Related
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 read a lot of topics which mention that the primary purpose for DataType is displaying data and not validating data. So I tried the following for testing
public partial class test
{
public int Id { get; set; }
[DataType(DataType.EmailAddress)]
public string email { get; set; }
[DataType(DataType.Date)]
public System.DateTime date { get; set; }
}
And I have noted that both the date & email will have validation checking,For example I can not write invalid email address or invalid date format ?
So my question is why a lot of topics mention that the primary purpose for DataType is used for formatting the properties and not for validating them. While in my test I found that specifying DataType for the property such as email & Date will create validation login also?
Can anyone advice?
Thanks
I have a model with a one-to-many relationship kinda similar to this:
public class people
{
public int id { get; set; }
public sting name { get; set; }
public virtual stuff things { get; set; }
}
public class stuff
{
public int id { get; set; }
public string name { get; set; }
public int thingType { get; set; }
}
I now need to be able to create and edit "stuff" for the person I am currently editing on my "editPeople" page. I'm using AJAX to create JQuery UI Dialog box for the stuff edit/create form, and then I post it back to the server to create a bunch of hidden fields so I can actually save this data later.
I'm concerned that these hidden fields would be named in a way that such that when I post my peopleEdit back to the controller, the Model binding won't properly convert the "stuff" that I have created/edited. Am I doing this wrong/Is there a better method? Am I forced into creating a custom model binder?
In my aproach would be if a people can have many stuff and you want to use ajax you can create a partial view to edit the stuff you would send the stuff object from people to the patial view action and run partial view action on the ajax call.
You may consider a javascript framework like Angular.js or Knockout.js to handle the data binding on the client. Then on submit, you can attach a function and the framework would provide you with the values on the model which you can submit to your server via AJAX.
Ref. this Microsoft's official video:
http://www.asp.net/web-api/videos/getting-started/custom-validation
I downloaded the code and run it. It's fine.
Then, I remove all the client validation attributes(data-val-*) from the html file. It didn't work fine. I could not see the validation messages on the web page.
My question is how to regular the server side validation messages and how to display them as client-side validation.
Why would you delete the validation attributes? That's exactly what gets you the validation messages. To change the validation tests, you need to set the appropriate validation attributes on the model properties, e.g.,
[Required]
public string Genre { get; set; }
[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
[StringLength(5)]
public string Rating { get; set; }
As described in this post on ASP.NET MVC 4 Model Validation.
First, let's see the following picture that explain the concept of .Net RIA Service.
(source: nikhilk.net)
As you see, the application has app logic (business rule) that can be implemented both server side (databases + Repositories + external services) and client side (asp.net web page + Silverlight + WCF)
Next, I create some data class that contains some validation rule.
namespace [SolutionName].Models
{
public interface IUser
{
Guid ID { get; set; }
[Required]
[StringLength(15)]
[RegularExpression("^[a-zA-Z][a-zA-Z_]+$")]
string LoginName { get; set; }
[Required]
[StringLength(255)]
string HashedPassword { get; set; }
DateTime CreateTime { get; set; }
[StringLength(255)]
string Description { get; set; }
[Required]
Role Role { get; set; }
}
}
After that, I create some custom Model Binder for validating data when users post it to controllers. So, I can ensure that every Model is valid before I save it.
public ActionResult SaveData()
{
if(ModelState.IsValid)
{
// logic for saving data
}
else
{
// logic for displaying error message
}
}
However, some view page doesn't require all of fields in data type. It needs some of field in data type. I can't separate this data type into multiple interfaces depend on what data field that view page requires. Because some of data fields are duplicate. Moreover, it will separate app logic too.
For example
LogOn view uses only 2 fields,
including LogOnName and
HashedPassword.
ChangePassword view use only 2 fields, including Id and
HashedPassword.
UserProfile view uses 4 field, including ID, LogOnName,
HashedPassword and Description.
Do you have any idea for solving this problem? I think it much like AOP concept.
By the way, I can solve this by adding a list field that contains unused fields. But this idea is quite bad when I use it with a large data type that contains more than 100 fields.
namespace [SolutionName].Models
{
public interface IUser
{
/*
Some defined data type
*/
// All fields that is contained in this list won't be validated by defined rules.
List<string> unusedFields { get;set; }
}
}
Thanks,
The fundamental issue here seems to be one of the following:
Contextual validation rules are being expressed as invariants
Entities with unsatisfied invariants are being prematurely created/validated
I would suggest that you don't attempt using Model Binders to instantiate and validate types for which all invariant information isn't obtainable from the Http request. In the case of LogOn, the only information you have is the user's name and password. Therefore, LogOn shouldn't expect a User type, but rather the username and password, perhaps encapsulated in a Credentials type.