Is it possible to toggle Validation Data Annotations on/off in MVC 3?

前端 未结 3 581
别跟我提以往
别跟我提以往 2021-01-13 20:36

I have two separate VIEWS accessing the same MODEL. When I put the validator data annotations on the model, it works as advertised and prevents the data from being submitte

3条回答
  •  北荒
    北荒 (楼主)
    2021-01-13 20:48

    I solved this problem using a different approach.

    The trick is not to disable validation per-se, but to clear any inappropriate validation errors before the controller's action is invoked (so ModelState.IsValid returns true).

    If a Model (or ViewModel) object requires custom validation then it implements an interface I defined called ICustomValidation which looks like this:

    public interface ICustomValidation {
        void PerformValidation(ModelStateDictionary modelState);
    }
    

    My BaseController class (which all of my controllers subclass) has this method override:

    protected override void OnActionExecuting(ActionExecutingContext filterContext) {
        base.OnActionExecuting(filterContext);
    
        // Unfortunately it seems this is the only way to get the Model object
        if( filterContext.ActionParameters.ContainsKey("model") ) {
    
            Object                    model = filterContext.ActionParameters["model"];
            ModelStateDictionary modelState = filterContext.Controller.ViewData.ModelState; // ViewData.Model always returns null at this point.
    
            ICustomValidation modelValidation = model as ICustomValidation;
            if( modelValidation != null ) {
                modelValidation.PerformValidation( modelState );
            }
        }
    
    }
    

    So in an example ViewModel class, if I want to disable (or rather: disregard) certain validation errors then it just needs to do this:

    public class SomeModel : ICustomValidation {
    
        [Required]
        public Boolean NamePresent { get; set; }
    
        [Required]
        public String Name { get; set; }
    
        public void PerformValidation(ModelStateDictionary modelState) {
            if( !NamePresent ) dict.Remove("Name");
        }
    }
    

    In my actual code there's a bit more logic that clears the ModelStateDictionary in a model-recursive and by-prefix method which keeps it robust.

    My solution does not match your problem exactly, but using a similar approach you should be able to get it to work for you.

提交回复
热议问题