"Transfer from" http://www.cnblogs.com/dozer/archive/2010/04/12/MVC-DataAnnotations.html author Dozer
Let me introduce you to MVC's data validation framework today.
In the 1.0 version, many friends have proposed how to use client authentication, today found some information, discovered the method of client authentication.
1. What are the advantages of the data validation framework in MVC?
In the ASP. NET era, or not using MVC's validation framework, data validation is typically performed in the BLL layer, but the return value of the BLL layer returns only one thing, such as a string, and in reality, data validation is complex.
At this time, the BLL layer and site will be detached from the incomplete, because many of the code has to be written on the site.
In the MVC data validation framework, it is possible to write data validation code in a model layer that is lower than the BLL layer, even without the BLL layer.
And finally can be displayed on the Web page.
This is the final effect of this picture.
2, in layman's?
This framework has an advantage and is very flexible, and I write it here with a normal three-tier architecture.
Because of the flexibility, I can write data validation on any level.
i) written in the controller: This is the simplest method, but it is also the least recommended method, because it does not reflect the layered mind
ii) written in the BLL: If you need to involve other data when validating a data, you should write the validation on this layer, such as the category value of a article model is 1, and query whether the classification exists
III) written in model: some of the underlying standards should be written on this layer, as these standards cannot be violated under any circumstances, such as the length of the account name cannot exceed 20 characters
Below, I will step by step 3 in the verification method introduced to everyone
3. Combination of front-end and back-end
People who have seen the MVC tutorial completely should know how to use modelstate, in fact, the MVC validation framework is using it to display the results of the validation on the page.
Let's look at an example:
Controller[HttpPost]
If the name attribute of input in the form is the same as the model field, it can be passed directly in the model form to an action
Public ActionResult EXP1 (Models.usermodel user)
{
Judge
if (user. Name.length >20)
{
If an error occurs, call Modelstate's Addmodelerror method, the first parameter needs to enter the field name of the error
Modelstate.addmodelerror ("name", "name must not exceed 20 characters");
}
Determine if there are errors in modelstate
if (modelstate.isvalid)
{
If there is no error, return to homepage
Return redirecttoaction ("Index");
}
Else
{
If there is an error, continue to enter information
return View (user);
}
}
Here in the controller in a action in the data validation, and put the results into the modelstate, then how to display on the front page?
If you do not understand the MVC validation framework, you can actually generate it directly and see the standard practice
Right-click on the code, click Add View
Select Create a strongly typed view and select Edit in the content
This is an auto-generated view
OK, below I can run the ...
Because the front-end Page view is automatically generated, so some readers may not understand, why I just in the back end of the data validation information will be displayed to the front?
In fact, the key is to use this: <%= html.validationmessagefor (model = model. Name)%>
Readers who do not understand the strongly typed method, or who are still using MVC1.0, can see this: <%= html.validationmessage ("Name")%>
(in addition to the Validationmessage function, there are several other functions, can achieve different effects, the reader can self-study, these functions are beginning with validation)
Summary: Validating data in a controller, putting it into modelstate (whose core is a dictionary), and then reading it using a function
This results in a combination of front-end and post-retransmitting data validation.
4, how to put data validation code into the business logic layer?
In the above section, we see the core of the MVC Data Validation framework, Modelstate.
As long as you add an error in the Modelstate, you can display it in the front page.
So, the key to this part is to let the BLL operate modelstate
Here, there are 2 methods to refer to, wherein the second scenario I refer to the xval to achieve
i) Scenario one: Pass in the Modelstate object directly when calling the BLL function
Advantages: This is best understood, I directly into the Modelstate object, let the BLL operation it can not?
Cons: The BLL is the business logic layer, and it should not know who it was called, that is to say, there should be no MVC-specific stuff in the BLL layer (Modelstate object)
Let me implement it as follows:
BLLUsing System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Web;
Using SYSTEM.WEB.MVC;
Namespace MVCAPPLICATION1.BLL
{
Publicstaticclass USERBLL
{
Publicstaticvoid Edit (models.usermodel user, modelstatedictionary modelstate)
{
if (user. Name.length >20)
{
If an error occurs, call Modelstate's Addmodelerror method, the first parameter needs to enter the field name of the error
Modelstate.addmodelerror ("name", "name must not exceed 20 characters");
}
if (modelstate.isvalid)
{
Here I can write some code, because the verification is complete, I can start to update the database
}
}
}
}
Controller[HttpPost]
Public ActionResult EXP2 (Models.usermodel user)
{
Calling functions in the BLL
Bll. Userbll.edit (user, modelstate);
if (modelstate.isvalid)
{
Return redirecttoaction ("Index");
}
Else
{
Here, the front page is not changed, so I directly take advantage of the front page in the first example
Return View ("Exp1", user);
}
}
OK, run directly, the result is the same as the previous method
Summary: When calling the BLL, pass the Modelstate
II) Scenario Two: Link the BLL with the controller by error trapping
If you use scenario one, a problem arises:
What if I don't use MVC for my project?
There is something similar to modelstate in the new architecture. Can't you just change all the BLL?
So, we need scenario two.
This is done by writing a custom exception class, and then this custom exception class has 2 features:
1. Add error
2. Convert the error to modelstate (if you want to transfer to another schema, you can write a new transfer method)
The following code is the custom exception class
modelexceptionsMust inherit from exception
Publicclass modelexceptions:exception
{
List that holds error messages
list<string[]> errors =new list<string[]> ();
Determine if there is an error
Publicbool IsValid
{
Get
{
return errors. Count ==0?true:false;
}
}
Add error message
Publicvoid adderror (string name, String message)
{
THIS.ERRORS.ADD (newstring[] {name, message});
}
Fill Modelstate
Publicvoid fillmodelstate (modelstatedictionary modelstate)
{
foreach (var e inthis.errors)
{
Modelstate. Addmodelerror (E[0], e[1]);
}
}
}
Next is the code in the controller
Controller[HttpPost]
Public ActionResult Exp3 (Models.usermodel user)
{
Use try to catch errors
Try
{
Bll. Userbll.edit (user);
}
catch (Modelexceptions e)
{
If an error occurs, it is populated into the modelstate
E.fillmodelstate (modelstate);
}
if (modelstate.isvalid)
{
Return redirecttoaction ("Index");
}
Else
{
Here, the front page is not changed, so I directly take advantage of the front page in the first example
Return View ("Exp1", user);
}
}
And then the code in the BLL
BLLPublicstaticvoid Edit (Models.usermodel user)
{
var e =new modelexceptions ();
if (user. Name.length >20)
{
If an error occurs, call Modelstate's Addmodelerror method, the first parameter needs to enter the field name of the error
E.adderror ("name", "name must not exceed 20 characters");
}
if (e.isvalid)
{
Here I can write some code, because the verification is complete, I can start to update the database
}
Else
{
Throw an error if there is an error
Throw e;
}
}
Summary: The simple practice, in the late will instead will bring a lot of trouble, so recommend scenario two. And plan two is not very troublesome, but it makes people feel very clear
5. How to put the data validation code into model?
Earlier, validating the data in the BLL was fine, but there was a problem
A model, many restrictions are fixed, such as the length can not exceed 20 characters
But I have a lot of processes in the BLL, such as modifying, deleting, etc.
Do I have to do more of this validation in all the process?
You can actually solve this problem by writing a function.
However, my (Model) name has no more than 20 characters is my own thing, why do you want to identify? I'm the Boss!
A: In my home, big things I decide, small things my wife is the Boss ~ What is the big deal? What is a trifle? Like the United States to fight Iraq, this is a big thing, everything else is small ...
OK, we have to ...
How to give data validation to model? You need to reference a DLL here
And then do that in the model.
ModelUsing System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Web;
Using System.ComponentModel.DataAnnotations;
Namespace Mvcapplication1.models
{
Publicclass Usermodel
{
Publicstring Name {get; set;}
attribute before adding attribute
[Required (errormessage = "Password cannot be empty")]
[Stringlength (errormessage = "Password length cannot exceed 20 characters")]
Publicstring Password {get; set;}
}
}
Refer to the System.ComponentModel.DataAnnotations namespace and precede the Model property with attribute (C # new feature: feature) so that you can
Check the System.ComponentModel.DataAnnotations namespace yourself to see what validation methods are available
Of course, you can also customize the validation, see the definition of the default validation, see which class it inherits, and write it by itself.
I'm not canceling this. Validation in the BLL, 2 kinds of verification can be mixed with
OK, what do you need to do in the controller and the BLL? We need to make some changes.
Controller[HttpPost]
MVC has been validated when it comes to this model and has misplaced the error modelstate
Public ActionResult EXP4 (Models.usermodel user)
{
Try
{
Other constant, except here, we need to pass in Modelstate.isvalid
Bll. Userbll.edit (User,modelstate.isvalid);
}
catch (Modelexceptions e)
{
E.fillmodelstate (modelstate);
}
if (modelstate.isvalid)
{
Return redirecttoaction ("Index");
}
Else
{
Return View ("Exp1", user);
}
}
BLLPublicstaticvoid Edit (Models.usermodel user,bool IsValid)
{
var e =new modelexceptions ();
if (user. Name.length >20)
{
E.adderror ("name", "name must not exceed 20 characters");
}
Nothing else, but here I have to judge whether there are errors in E, but also whether there are errors in modelstate
if (e.isvalid && IsValid)
{
Here I can write some code, because the verification is complete, I can start to update the database
}
Else
{
Throw e;
}
}
I annotated the place where the last example was changed.
and mixed with the 2 verification method
When do you use model validation? Verifying the intrinsic properties of the model
When to use the BLL to verify? When it's time to validate some complex relationships
In addition, why do you want to pass modelstate.isvalid into the BLL?
Because model validation is done when the model is passed into this method.
If not passed in, the BLL verifies that although there is no error, it does not mean that the whole process is not wrong.
The operation of the database to know the complete authentication information, if not passed, will cause the program bug
Summary: A reasonable position to place the data verification code according to the situation is kingly
6. How do I change the style of the error prompt?
I'm using the MVC basic routine, which contains the CSS style sheet.
By default, text messages such as "name too long" appear, but there is no style (default is normal font, normal color)
How to modify it?
In fact, open MVC default CSS stylesheet is not difficult to find, these error messages have a fixed class, so just write a CSS class can be
How do you know what the class name is? The most convenient way to do the page after the browser can be seen
7, in the Entity framework, how to write data validation in model?
The Entity framework automatically generates the model, although it can be modified, but it is highly recommended not to directly modify the model original code
In fact, Microsoft has long thought of this point, it generated the model is the partial class (some classes)
That is, the code of the same class can be divided into several parts, written in different places
This is written in a different place, but it needs to be in the same namespace
User[Metadatatype (typeof (Usermetadata))]
Publicpartialclass User {}
Publicclass Usermetadata
{
[Required (errormessage = "name is empty")]
[Stringlength (errormessage = "name cannot be longer than 10 characters")]
Publicstring Name {get; set;}
[Required (errormessage = "Password is empty")]
[Stringlength (errormessage = "Password length must not exceed 20 characters")]
Publicstring Password {get; set;}
[Required (errormessage = "account is empty")]
[Stringlength (errormessage = "account length must not exceed 10 characters")]
Publicstring Passport {get; set;}
}
Once this is written, you can use model validation in the Entity Framework
1. Non-null and data type validation 1 [Required] 2 [Display (name = "username")] 3 public string UserName {get; set;} 4 5 [Required] 6 [DataType (Datatype.password)] 7 [Display (Name = "password")] 8 public string Password {get; set;} 9 [required]11 [DataType (datatype.emailaddress)]12 [Display (Name = "e-mail Address")]13 public String Email {get; set;} 2. Non-null and character length verification 1 [Required (errormessage= "username cannot be empty!) ")]2 [DisplayName (" username ")] 3 public string UserName {get; Set }4 5 [DisplayName ("password")]6 [Stringlength (6,errormessage=) password length cannot exceed 6 characters! ")]7 public string Password {get; Set }3. Domain validation 1 [DisplayName ("Age")]2 [Range (1,int. Maxvalue,errormessage= "Age cannot be less than 1! ")] 3 public int age {get; Set }4. Compare validation 1 [required]2 [DataType (Datatype.password)]3 [DisplayName ("password")]4 public string Pas Sword {get; set;} 5 6 [DataType (Datatype.password)]7 [DisplayName ("Confirm password")]8 [Compare ("Password", errormessage = "Password and Confirm password do not match! ")]9 public string ConfirmPassword {get; Set }5. Regular expression Validation 1 [DisplayName ("Contact phone")]2 [RegularExpression (@ "^ (0\d{2,5}-) |\ (0\d{2,5}\))? \d{7,8} (-\d{3,4})? $", E Rrormessage = "The phone format is not correct!" \ n Valid format: \n① 7 or 8 digit number [-3 or 4-digit extension number, optional]\n② (area code) 7 or 8-digit number [-3 or 4-digit extension, optional]\n③3~5 area code-7 or 8-digit number [-3 or 4-digit extension number, optional]\ n Example: 023-12345678; (023) 1234567-1234 ")]3 public string Phone {get; set;} 4 [DisplayName ("E-mail")]5 [RegularExpression (@ "^\w+ ((-\w+) | ( \.\w+)) *\@[a-za-z0-9]+ ((\.| -) [a-za-z0-9]+] *\. [a-za-z0-9]+$ ", errormessage =" Please enter the correct email format! " \ n Example: [email protected] ")]6 public string Email {get; set;} 7 [DisplayName ("url")]8 [RegularExpression ("@" http (s)?:/ /([\w-]+\.) +[\w-]+ (/[\w-/?%&=]*)?, errormessage = "Please enter a valid URL!\n example: https://abc.com;http://www.abc.cn")]9 public string H ttpaddress {get; set;} 6. Custom validation 1 [required]2 [validatepasswordlength]3 [DatatyPE (Datatype.password)]4 [DisplayName ("password")]5 public string Password {get; set;} 1 [AttributeUsage Tributetargets.field | Attributetargets.property, AllowMultiple = False, inherited = True)] 2 public sealed class Validatepasswordlengthattri Bute:validationattribute, iclientvalidatable 3 {4 Private const string _defaulterrormessage = "' {0} ' must contain at least {1} characters. "; 5 private readonly int _mincharacters = Membership.Provider.MinRequiredPasswordLength; 6 7 public Validatepasswordlengthattribute () 8:base (_defaulterrormessage) 9 {10}11 public override string Formaterrormessage (string name)-{String.Format return (Culturei Nfo. CurrentCulture, errormessagestring,15 name, _mincharacters);}17 public override bool IsValid (object value), {valueasstring = value as string;21 return (Valueasstri Ng! = null && valueasstring.length >= _mincharacters);}23 public ienumerable<modelclientvalidation Rule> getclientvalidationrules (Modelmetadata metadata, ControllerContext context) (new[) ]{27 New Modelclientvalidationstringlengthrule (Formaterrormessage (metadata. GetDisplayName ()), _mincharacters, Int. MaxValue) 28};29}30}※※※※※※※※※※
8. How to use client Authentication
Any platform can rely on JS to achieve client-side validation, but I am here to explore the MVC data validation.
What is the difference between MVC's client-side data validation?
The difference is that you don't have to write a line of JavaScript code!
Let's implement it now.
To add 3 JavaScript files first, add them sequentially:
Then add a line of code to the view: (Note to add before the form)
Note: Here, this is actually the function to convert the model validation into JavaScript code, right! It can only convert model verification, the BLL validation cannot be converted, because the BLL validation involves complex code, it is not possible to convert all to JavaScript it? And the BLL verifies that many also need to interact with the database.
What if you want to validate the BLL as a "client"? (It is possible to implement no refresh validation with Ajax, not real client-side validation)
So far, it's just handwriting.
If there is a harvest, I will continue to update ~
MVC data Validation "Go"