Common attribute verification in mvc

The client validation logic gives an immediate feedback on the data entered by the user into the form. The reason why server-side authentication is needed is that the information from the network can not be trusted.

When talking about validation in the context of ASP.NET MVC design pattern, the main concern is to validate the values of the model

    Data annotation features are defined in the namespace System.ComponentModel.DataAnnotations, which provide server-side validation. The framework also supports client-side validation when using these properties on model properties. In namespace data annotations, there are four features that can be used to deal with general validation situations.

1.1 Required

Because the customer's name is Required, you need to add the Required attribute to the attributes of the model class

1 [Required]
2 public string FirstName{ get; set;}

  When the property is null or empty, the Required attribute will raise a validation error.


1.2 StringLength

Check the length of the data

1 [Required]
2 [StringLength(160)]
3 public string FirstName { get; set;}

When the data length exceeds 160, it will be prompted. The MinimumLength parameter is an option to set the minimum length of the string as follows (length > = 3 and < = 160)

1 [Required]
2 [StringLength(160, MinimumLength=3)]
3 public string FirstName { get; set;}


1.3 RegularExpression

Used for regular expression validation, used for mailbox, phone and other properties.

1 [RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
2 public string Email {get; set;}


1.4 Range

The Range property is used to specify the minimum and maximum values of numeric type values.

The age limit is between 35 and 44:

1 [Range(35,44)]
2 public int Age {get; set;}

The limited price is between 0.00 and 49.99. This overload method can limit the data type:

1 [Range(typeof(decimal),"0.00", 49.00)]
2 public decimal Price {get; set;}


 1.5 Compare

The Compare feature ensures that the two properties of the model object have the same value. It is generally used to verify the repeated input data of the customer

 public string Email {get; set;}

 public string EmailConfirm {get; set;}

If the e-mail addresses entered twice are inconsistent, you will be prompted.


1.6 Remote

The ASP.NET MVC framework also adds an additional Remote authentication feature for applications in the namespace System.Web.Mvc.

The Remote feature can use the callback function on the server side to execute the verification logic on the client side. For example, to avoid generating users with the same user name in the database during user registration, you can use the Remote feature to send the UserName value to the server, and then compare it with the corresponding table field value in the server-side database:

1 [Remote("CheckUserName", "Account")]
2 public string UserName {get ; set;}

In the attribute, you can set the name of the controller and the operational name to be called by the client code. The client code will automatically send the UserName attribute value entered by the user to the server. An overloaded construction method of this feature also allows you to specify other fields to be sent to the server:

1 public JsonResult CheckUserName (string username)
2 {
3    var result = Membership.FindUserByName(username).Count ==0 ;
4    return Json(result, JsonRequestBehavior.AllowGet);  
5 }

The above controller operation will validate with a parameter with the same name as the UserName attribute and return a Boolean value (true or false) encapsulated in the JacaScript Object Notation (JSON) object


2.1 custom error message and its localization

Each validation feature allows you to pass a parameter with a custom error message.

1 [Required( ErrorMessage = "Your last name is required")]
2 [StringLength(160, ErrorMessage="Your last name is too long")]
3 public string LastName {get ; set ;}

  The custom error message also has a format item in the string. The built-in feature formats the error message string with a friendly property display name

1  [Required( ErrorMessage = "Your {0} is required")]
2  [StringLength(160, ErrorMessage="Your last name is too long")]
3  public string LastName {get ; set ;}

If the application is multilingual, hard coding is not applicable. You can specify resource types and resource names for localized error messages for both validation features.

1 [Required(ErrorMessageResource = typeof(ErrorMessages),
2 ErrorMessageResourceName="LastNameRequired")]
3 [StringLength(160, ErrorMessageResourceType = typeof(ErrorMessage),
ErrorMessageResourceName = "LastNameTooLong")] 4 public string LastName { get; set;}


3. Custom verification logic

   Two core application methods:

  • Encapsulate the validation logic in a custom data annotation
  • Encapsulate validation logic in model objects

      Encapsulating the validation logic in the user-defined data annotation can realize the reuse logic in multiple models, which requires writing code inside the feature to deal with different types of models, but once implemented, the new annotation can be reused in multiple places.

      On the other hand, if the verification logic is directly put into the model object, it means that the verification logic can be easily coded and implemented, because it only needs to care about the verification logic of one model object, which makes it convenient to make some assumptions about the state and structure of the object, but this way is not conducive to the reuse of logic.


3.1 user defined annotation

      All validation annotations (such as Required and Range) attributes are ultimately derived from the base class ValidationAttribute, which is an abstract class defined in the namespace System.ComponentModel.DataAnnotations. Therefore, the validation logic of the program must also derive from the ValidationAttribute class:

1 using System.ComponentModel.DataAnnotations;
3 namespace MvcMusicStore.Infrastructure
4 {
5     public clsaa MaxWordsAttribute : ValidationAttribute
6     {
7     .......
8     }
9 }

To implement the validation logic, you need to override at least one version of the IsValid method provided in the base class. The ValidationContext parameter used when overriding the IsValid method provides a lot of information that can be used inside the IsValid method, such as model type, model object instance, humanized display name used to verify properties, and other useful information.  

Verify the number of words entered here and set the default error message:

 1  using System.ComponentModel.DataAnnotations;
 3  namespace MvcMusicStore.Infrastructure
 4  {
 5      public clsaa MaxWordsAttribute : ValidationAttribute
 6      {
 7         public MaxWordsAttribute(int maxWords) : base("{0} has too many words.")    
 8         {
 9          _maxWords = maxWords;
10         }
12         protected override ValidationResult IsValid(object value, 
ValidationContext validationContext) 13 { 14 var valueAsString = value.ToString(); 15 if( valueAsString.Split(' ').Length > _maxWords) 16 { 17 var errorMessage = FormatErrorMessage(validationContext.DisplayName); 18 return new ValidationResult(errorMessage); 19 } 20 return ValidationResult.Success; 21 }
22 private readonly int _maxWords; 23 } 24 }

      FormatErrorMessage can use the appropriate error prompt message string (even if the string is stored in a local resource file). This code statement needs to pass the value of the name attribute, which can be obtained through the DisplayName attribute of the validationContext parameter. After the validation logic is constructed, it can be applied to any model attribute:

1 [Required]
2 [StringLength(160)]
3 [MaxWords(10)]
4 public string LastName {get ; set ;}

You can even assign a custom error message to the property:

1  [Required]
2  [StringLength(160)]
3  [MaxWords(10, ErrorMessage = "There are too many words in {0}")]
4  public string LastName {get ; set ;}



A self validating model is a model object that knows how to validate itself. A model object can verify itself by implementing the IValidatableObject interface. The following is a direct check of the number of items in the LastName field in the Order model:


 1 public class Order : IValidatableObject
 2 {
 3     public IEnumerable<ValidationResult> Validate(ValidationContext ValidationContext)
 4     {
 5         if(LastName != null && LastName.Split(' ').Length > 10)
 6         {
 7             yield return new ValidationResult("The last name has too many words!",
new []{"LastName"}); 8 } 9 //.... 10 } 11 }


There are several obvious differences between this method and the feature version:

  • The method name called by the MVC runtime to perform validation is Validate instead of IsValid, but more importantly, their return types and parameters are different
  • The return type of Validate is IEnumerable < ValidationResult >, not a separate ValidationResult object. On the surface, the internal validation logic validates the entire model, so multiple validation errors may be returned.
  • There is no value parameter passed to the Validate method, because Validate is a model instance method in which you can directly access the property value of the current model object.



4. Display and edit annotations

4.1 Display

      The Display property sets a friendly Display name for model properties

1  [Required]
2  [StringLength(160)]
3  [Display(Name="Last Name", Order=15001)]
4  public string FirstName { get; set;}


4.2 ScaffoldColumn

    The scaffold column feature can hide some properties rendered by HTML auxiliary methods such as EditorForModel and DisplayForModel:

1 [ScaffoldColumn(false)]
2 public string Username {get; set;}

After adding this feature, the EditorForModel helper will no longer display the input element and Label label for the Username field. Note, however, that if the model binder sees a matching value in the request, it will still try to assign a value to the Username attribute.


4.3 DisplayFormat

By naming parameters, the DisplayFormat property can be used to handle various formatting options for properties. When an attribute contains a null value, you can provide optional display text, turn off HTML encoding for the attribute containing the tag, and specify a format string applied to the attribute value for the runtime.

The following code formats the Total attribute value of the model as a monetary value:

1 [DisplayFormat ( ApplyFormatInEditMode = true, DataFormatString "{0:c}")]
2 public decimal Total {get; set;}


4.4 ReadOnly

If you need to ensure that the default model binder does not update the property with the new value in the request, you can add the ReadOnly attribute to the property:

1 [ReadOnly(true)]
2 public decimal Total {get; set;}


4.5 DataType

The DataType attribute provides the runtime with specific usage information about properties. For example, a property of type String can be applied to an e-mail address, URL, or password. The DataType feature meets all these requirements:

1 [Required]
2 [DataType(DataType.Password)]
3 [Display(name="Password")]
4 public string Password {get; set;}

Other data types include Currency, Date, Time, and MultilineText.


Posted on Fri, 03 Dec 2021 20:38:35 -0500 by Deposeni