Best Practices ViewModel Validation in ASP.NET MVC

后端 未结 4 690
别那么骄傲
别那么骄傲 2020-12-02 08:42

I am using DataAnnotations to validate my ViewModel on client side with jquery.validate.unobtrusive and on server side in ASP.

4条回答
  •  不思量自难忘°
    2020-12-02 09:35

    Like others have said, there is no such tricks, no easy way to centralize your validations.

    I have a couple of approaches that might interest you. Take note that this is how "we" solved the same problem before. Its up to you if you can find our solution maintainable and productive.

    I know that there is a problem with Add/Edit ViewModels that could have similar fields but different ValidationRules.

    Inheritance Approach

    You can achieve centralized validation using a base class, and use subclasses for specific validations.

    // Base class. That will be shared by the add and edit
    public class UserModel
    {
        public int ID { get; set; }
        public virtual string FirstName { get; set; } // Notice the virtual?
    
        // This validation is shared on both Add and Edit.
        // A centralized approach.
        [Required]
        public string LastName { get; set; }
    }
    
    // Used for creating a new user.
    public class AddUserViewModel : UserModel
    {
        // AddUser has its own specific validation for the first name.
        [Required]
        public override string FirstName { get; set; } // Notice the override?
    }
    
    // Used for updating a user.
    public class EditUserViewModel : UserModel
    {
        public override string FirstName { get; set; }
    }
    

    Extending the ValidationAttribute Approach

    Using custom ValidationAtribute, you can achieve centralized validation. This is only the basic implementation, I am just showing you the idea.

    using System.ComponentModel.DataAnnotations;
    public class CustomEmailAttribute : ValidationAttribute
    {
        public CustomEmailAttribute()
        {
            this.ErrorMessage = "Error Message Here";
        }
    
        public override bool IsValid(object value)
        {
            string email = value as string;
    
            // Put validation logic here.
    
            return valid;
        }
    }
    

    You would use as such

    public class AddUserViewModel
    {
        [CustomEmail]
        public string Email { get; set; }
    
        [CustomEmail]
        public string RetypeEmail { get; set; }
    }
    

    Is there any better way to initialize validation on new DOM elements that received with ajax call other that I mention?

    This is how I rebind validators on dynamic elements.

    /** 
    * Rebinds the MVC unobtrusive validation to the newly written
    * form inputs. This is especially useful for forms loaded from
    * partial views or ajax.
    *
    * Credits: http://www.mfranc.com/javascript/unobtrusive-validation-in-partial-views/
    * 
    * Usage: Call after pasting the partial view
    *
    */
    function refreshValidators(formSelector) {
        //get the relevant form 
        var form = $(formSelector);
        // delete validator in case someone called form.validate()
        $(form).removeData("validator");
        $.validator.unobtrusive.parse(form);
    };
    

    Usage

    // Dynamically load the add-user interface from a partial view.
    $('#add-user-div').html(partialView);
    
    // Call refresh validators on the form
    refreshValidators('#add-user-div form');
    

提交回复
热议问题