Validate winform bằng SpecExpress

SpecExpress là một Fluent validation framework, trong bài viết này, tôi xin giới thiệu cách validate Winform bằng SpecExpress và Error provider.

Xem giới thiệu về SpecExpress.

Trước hết tạo một Entity kế thừa từ IDataErrorInfo interface.

image

Sau đó tạo một dictionary đẻ lưu lại các message lỗi của các Property trong Entity đó.

   1: /// <summary>

   2:        /// Dictionary of validation errors, it contains Property and Error messages...

   3:        /// </summary>

   4:        public Dictionary<string, string> Errors

   5:        {

   6:            get;

   7:            set;

   8:        }

 

Việc tiếp theo là implement interface IDataError: index this và thuộc tính Error:

   1: public string Error

   2:        {

   3:            get

   4:            {

   5:                return lastError; 

   6:            }

   7:              

   8:        }

index this[propertyName] trả về Error message cho Error Provider

 

   1: /// <summary>

   2:     /// Gets the error of a specific property

   3:     /// </summary>

   4:     /// <param name="propertyName">The property name</param>d

   5:     /// <returns>The error message</returns>

   6:     public string this[string propertyName]

   7:     {

   8:         #region Doan Manh Ha commented for write new Error validation method by Specexpress

   9:         //get { return _propError[propertyName]; }

  10:         //set 

  11:         //{

  12:         //    _propError[propertyName] = value;

  13:         //    PropertyHasChanged(); 

  14:         //}

  15:         #endregion

  16:  

  17:         get

  18:         {

  19:             if (!IsNeedValidation)

  20:             {

  21:                 if (Errors!=null && Errors.ContainsKey(propertyName))

  22:                     return Errors[propertyName];

  23:                 else

  24:                     return string.Empty;

  25:             }

  26:  

  27:             var notification = this.ValidateProperty(propertyName);

  28:  

  29:             

  30:  

  31:             if (notification==null || notification.IsValid)

  32:             {

  33:                 lastError = string.Empty;

  34:                

  35:             }

  36:             else

  37:             { 

  38:                 // TODO: aggregate notification messages in readable form and assign to lastError 

  39:                 lastError = this.BuildErrorMessages(notification.ErrorSummary());

  40:             }

  41:  

  42:             AddError(propertyName, lastError);

  43:             return lastError;

  44:         }

  45:         set

  46:         {

  47:             AddError(propertyName, value);

  48:         }

  49:  

  50:     }

– IsNeedValidation là một thuộc tính xác định xem có cần phải validate không.

– Validate chính là Virtual method để validate property đó, trả về ValidationNotification

   1: protected virtual ValidationNotification ValidateProperty(string propertyName)

   2:     {

   3:         throw new NotImplementedException();

   4:     }

AddError là hàm add nội dung Error vào Error dictionary:

   1: private void AddError(string propertyName, string error)

   2:         {

   3:             //lastError = value;

   4:             if (Errors == null)

   5:                 Errors = new Dictionary<string, string>();

   6:  

   7:             if (Errors.ContainsKey(propertyName))

   8:                 Errors[propertyName] = error;

   9:             else

  10:                 Errors.Add(propertyName, error);

  11:         }

 

Tiếp theo ta viết Entity cho User, kế thừa từ AbstractBaseData:

 

   1: public class User:AbstractBaseData<int>

   2:    {

   3:  

   4:        private int id;

   5:        private string name;

   6:        private string password;

   7:        private string rules;

   8:  

   9:        #region Public properties

  10:  

  11:        public int Id

  12:        {

  13:            get

  14:            {

  15:                return this.id;

  16:            }

  17:            set

  18:            {

  19:                if ((this.id != value))

  20:                {

  21:                    this.id = value;

  22:                    this.OnPropertyChanged("Id");

  23:  

  24:                }

  25:            }

  26:        }

  27:  

  28:        public string Name

  29:        {

  30:            get

  31:            {

  32:                return this.name;

  33:            }

  34:            set

  35:            {

  36:                if ((this.name != value))

  37:                {

  38:                    this.name = value;

  39:                    this.OnPropertyChanged("Name");

  40:  

  41:                }

  42:            }

  43:        }

  44:  

  45:        public string Password

  46:        {

  47:            get

  48:            {

  49:                return this.password;

  50:            }

  51:            set

  52:            {

  53:                if ((this.password != value))

  54:                {

  55:                    this.password = value;

  56:                    this.OnPropertyChanged("Password");

  57:  

  58:                }

  59:            }

  60:        }

  61:  

  62:        public string Rules

  63:        {

  64:            get

  65:            {

  66:                return this.rules;

  67:            }

  68:            set

  69:            {

  70:                if ((this.rules != value))

  71:                {

  72:                    this.rules = value;

  73:                    this.OnPropertyChanged("Rules");

  74:  

  75:                }

  76:            }

  77:        }

  78:  

  79:        public IList<Role> Roles

  80:        {

  81:            get;

  82:            set;

  83:        }

  84:  

  85:        #endregion

  86:  

  87:        #region Validations

  88:  

  89:        UserSpecification spec = new UserSpecification();

  90:  

  91:        protected override ValidationNotification ValidateProperty(string propertyName)

  92:        {

  93:  

  94:            try

  95:            {

  96:  

  97:                return ValidationCatalog.ValidateProperty(this, propertyName, spec);

  98:            }

  99:            catch (Exception)

 100:            {

 101:                return null;

 102:            }

 103:        }

 104:  

 105:        public override bool Validate()

 106:        {

 107:           

 108:            this.IsNeedValidation = true;

 109:           

 110:            this.PropertyHasChanged();

 111:            this.IsNeedValidation = false;

 112:            return this.IsValid;

 113:        }

 114:        #endregion

 115:    }

 

Và Specification cho User entity:

   1: public class UserSpecification:Validates<User>

   2:   {

   3:       public UserSpecification()

   4:       {

   5:           Check(user => user.Name).Required(ValidationConstants.USER_NAME_REQ);

   6:  

   7:           Check(user => user.Password).Required(ValidationConstants.PASSWORD_REQ)

   8:                                       .MinLength(6);

   9:  

  10:           Check(user => user.Roles).Required(ValidationConstants.USER_ROLE_REQ);

  11:       }

  12:   }

Xử lý ở Winform UI

image

Sự kiện cho button Cập nhật:

   1: private void btnUpdate_Click(object sender, EventArgs e)

   2:    {

   3:        string typeOfUserViewData = typeof(UserViewData).Name;

   4:        UserViewData userViewData = this.GetSessionData(typeOfUserViewData) as UserViewData;

   5:        

   6:        var isValid = userViewData.User.Validate();

   7:        

   8:        //Récupération de la VSD

   9:        if (!isValid)

  10:        {

  11:            epUserView.DataSource = userViewData.User;

  12:            return;

  13:        }

  14:  

  15:        

  16:        userViewData.IsCreation = false;

  17:        //Transfert de l'exécution vers le controleur

  18:        //this.InvokeController(ControllerConstants.USER_CONTROLLER, ControllerActionConstants.SAVE_ACTION);   

  19:    }

Và đây là kết quả:

image

One thought on “Validate winform bằng SpecExpress

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s