In "asp.net mvc modelvalidator as the core model verification system: Modelvalidator" We introduced asp.net MVC for model validation of the four kinds of modelvalidator, So how did these modelvalidator be created? Many of the components of ASP.net mvc (such as modelbinder and filter) use a provider based delivery mechanism, which tells you about these modelvalidator modelvalidatorprovider.
First, Modelvalidatorprovider
We create the corresponding modelvalidator by registering the Modelvalidatorprovider, all modelvalidatorprovider directly or indirectly inherit the type Modelvalidatorprovider. As the following code fragment shows, the Modelvalidator provides implementations in an abstract method getvalidators, and returns a Modelvalidator collection.
1:public Abstract class Modelvalidatorprovider
2: {
3: Public abstract ienumerable<modelvalidator> getvalidators (Modelmetadata metadata, Modelbindingexecutioncontext context);
4:}
Because the data value provided by Valueprovider is limited to simple types, the model binding for a complex type uses a recursive procedure to bind all properties that act as a model object. Model validation can be seen as a follow-up link to the model binding, it to the binding data implementation validation, so model validation is also a recursive process, it uses the attribute based on the validation rules on the binding property value implementation validation. The Getvalidators method has two parameters, and the metadata parameter for the type modelmetadata is used or the corresponding validation rule. The parameter context is the Modelbindingexecutioncontext object that represents the current model binding contexts.
Second, Dataannotationsmodelvalidator
The Modelvalidatorprovider type of the dataannotationsmodelvalidator corresponding to the verification method of the data annotation attribute is Dataannotationsmodelvalidatorprovider 。 As shown in the following code fragment, Dataannotationsmodelvalidatorprovider inherits from another abstract type Associatedvalidatorprovider.
1:public class Dataannotationsmodelvalidatorprovider:associatedvalidatorprovider
2: {
3: //other Members
4: Public dataannotationsmodelvalidatorprovider ();
5: protected override ienumerable<modelvalidator> getvalidators (Modelmetadata metadata, ControllerContext context,ienumerable<attribute> attributes);
6:}
The so-called "Association (Association)" in the type name Associatedvalidatorprovider actually represents the associated list of attributes. That is, it provides the corresponding modelvalidator based on the list of attributes that are used to define validation rules from the model metadata. As shown in the following code fragment, Associatedvalidatorprovider defines a protected virtual method GetTypeDescriptor used to get a description object of the specified type (its type implements an interface ICustomTypeDescriptor). The analytic correlation characteristic finally passes through the abstract Getvalidators method realizes to the modelvalidator the provision, And Dataannotationsmodelvalidatorprovider is implementing this method to create the corresponding Dataannotationsmodelvalidator list.
1:public Abstract class Associatedvalidatorprovider:modelvalidatorprovider
2: {
3: protected Virtual ICustomTypeDescriptor gettypedescriptor (type type);
4: Public sealed override ienumerable<modelvalidator> getvalidators (Modelmetadata metadata, ControllerContext context);
5: protected abstract ienumerable<modelvalidator> getvalidators (modelmetadata metadata, ControllerContext Context, ienumerable<attribute> attributes);
6:}
In the overridden Getvalidators method, if the current model metadata is based on a property (which means that the containertype of the container type is not NULL and has a property name), When the GetTypeDescriptor method is invoked to get the container type description object, the PropertyDescriptor object used to describe the property is obtained based on the property type. Finally, the description object is used to get all the attributes applied on the corresponding attribute and invoke the abstract method getvalidators returns a Modelvalidator list based on the attribute. For non-attribute model metadata, the model type description object is obtained directly by calling the GetTypeDescriptor method. It then gets all the attributes applied to the model type and passes in the abstract method Getvalidators implementation of the Modelvalidator for the model type.
Third, Clientdatatypemodelvalidatorprovider
The Numericmodelvalidator and datemodelvalidator of client-side validation for numeric and date types are ultimately provided through Clientdatatypemodelvalidatorprovider with the following definitions. In the Getvalidators method, it determines whether a numeric type/datetime type is based on the specified model metadata, and if so, returns a single numericmodelvalidator/ A Modelvalidator collection of Datemodelvalidator objects. The data types considered to be numeric values here include Byte, sbyte, short, ushort, int, uint,long, ulong, float, double, and decimal.
1:public class Clientdatatypemodelvalidatorprovider:modelvalidatorprovider
2: {
3: Public clientdatatypemodelvalidatorprovider ();
4: Public override ienumerable<modelvalidator> getvalidators (Modelmetadata metadata, ControllerContext context);
5:}
Four, Dataerrorinfomodelvalidatorprovider
Two specific dataerrorinfomodelvalidator, That is, Dataerrorinfoclassmodelvalidator and dataerrorinfopropertymodelvalidator are ultimately provided through Dataerrorinfomodelvalidatorprovider with the following definitions 。 For the specific implementation of getvalidators, if the model type implements the IDataErrorInfo interface, Creates a Dataerrorinfoclassmodelvalidator object in the returned Modelvalidtor collection based on the established model metadata and controller context. For model metadata based on attributes, if the container type implements the IDataErrorInfo interface, The Modelvalidtor collection returned by this method also contains a Dataerrorinfopropertymodelvalidator object that is created based on the specified model metadata and controller context.
1:public class Dataerrorinfomodelvalidatorprovider:modelvalidatorprovider
2: {
3: Public dataerrorinfomodelvalidatorprovider ();
4: Public override ienumerable<modelvalidator> getvalidators (Modelmetadata metadata, ControllerContext context);
5:}
To give readers a better understanding of the Dataerrorinfomodelvalidator validation rules, and to define the delivery mechanism for it in Dataerrorinfopropertymodelvalidator, let's demonstrate a simple example. In an empty Web application created through the ASP.net MVC project template for Visual Studio, we define the following contact type that implements the IDataErrorInfo interface.
1:public class Contact:idataerrorinfo
2: {
3: Public string Error
4: {
5: Get {return "Invalid contact person!" ";}
6: }
7: Public string this[string ColumnName]
8: {
9: Get
%: {
One: switch (columnName)
: {
Case ' name ': Return ' name is required! ";
"Phoneno" : Return "phone number format Error! ";
Case "Emailadderss": Return "Invalid e-mail address!" ";
: default : return null;
: }
: }
: }
Public string Name {get; set;}
: Public string Phoneno {get; set;}
Public string Emailadderss {get; set;}
23:}