Wednesday, 28 March 2012

Asp.net mvc DataAnnotation ValidateAttribute two properties comparison.

Using Datannotion is great but there are scenarious in which the current attributes compare, range etc becomes inadequate especially for the comparisions. So we create here our own custom validation using ValidationAttribute class which is the base class for all the annotation attributes. So by deriving from it and overriding the Isvalid method we can create our custom attribute for the model.

So here is the scenario in which I will be validating the Username against the password which should not be equal. Compare attribute cannot be used in this scenario so I have created a custom attribute for that. Here is the model with the attribute.

User View Model
    [CompareUserPass("UserName", "Password", ErrorMessage = "UserName and password cannot be equal")]
    public class UserView
    {
        [Required(ErrorMessage = "UserName Required")]
        public string UserName
        {
            get;
            set;
        }
        [Required(ErrorMessage = "Password Required")]
        public string Password
        {
            get;
            set;
        }
         
        public string ConfirmPassword
        {
            get;
            set;
        }
     }

Note in the model above I had covered two properties comparision here so the attribute is at the top of the class and to validate one property you specify the attribute with that property which I have not covered here.

Custom Validation attribute class
     [AttributeUsage(AttributeTargets.Class)]
     public class CompareUserPassAttribute : ValidationAttribute
     {
        private string Property1 { get; set; }
        private string Property2 { get; set; }

        public CompareUserPassAttribute(string PropertyName1, string PropertyName2)
        {
             Property1 = PropertyName1;
             Property2 = PropertyName2;
        }

        public override Boolean IsValid(Object value)
        {
            if (Property1 == null && Property2 == null)
                return true;
            else
            {
                PropertyDescriptorCollection propertiess = TypeDescriptor.GetProperties(value);
                object originalValue1 = propertiess.Find(Property1, true).GetValue(value);
                object originalValue2 = propertiess.Find(Property2, true).GetValue(value);
                if (!originalValue1.Equals(originalValue2))
                    return true;
                else
                    return false;
            }
        }
     }


View

@model MvcApplication22.Models.UserView
@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <title>Creates</title>
</head>
<body>
    <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>UserView</legend>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.UserName)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.UserName)
                @Html.ValidationMessageFor(model => model.UserName)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.Password)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Password)
                @Html.ValidationMessageFor(model => model.Password)
            </div>
    
            <div class="editor-label">
                @Html.LabelFor(model => model.ConfirmPassword)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.ConfirmPassword)
                @Html.ValidationMessageFor(model => model.ConfirmPassword)
            </div>
    
            <p>
                <input type="submit" value="Create" />
            </p>
        </fieldset>
    }
    
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
</body>
</html>

2 comments:

  1. Is this custom validation work on client side?

    ReplyDelete
  2. yes it will work on the client side.

    ReplyDelete