【问题标题】:ASP.NET MVC Validation Groups?ASP.NET MVC 验证组?
【发布时间】:2011-11-12 12:50:38
【问题描述】:

我有一个表单,我想根据按下的提交按钮要求不同的字段。示例:如果您按下提交按钮 1,则需要字段 A,但如果您按下提交按钮 2,则只需要字段 B。如果我仍在使用 Web 表单,我将为每个按钮/验证器组合分配不同的“验证组”。 有没有办法在 MVC 中做到这一点,最好在模型上使用数据注释?我更愿意使用单一解决方案来实现客户端和服务器验证,但我会尽我所能......

提前致谢!

【问题讨论】:

    标签: .net asp.net-mvc asp.net-mvc-3 validation


    【解决方案1】:

    启用客户端验证的自定义验证属性怎么样(这样您可以获得客户端和服务器验证)?下面的解决方案使用 jQuery 不显眼的验证。要使用它,您需要为所有按钮指定特定名称并将名称传递给验证属性。该按钮还需要具有某种值,以便可以将其回发(因此服务器端代码可以对其进行测试,即<input type="submit" name="myButton" value="1" />)。我还没有测试过这段代码,所以我不确定它是否开箱即用。您可能需要制作一些模组:

    模型的验证属性:

    public class RequiredIfButtonClickedAttribute : ValidationAttribute, IClientValidatable
    {
        private RequiredAttribute _innerAttribute = new RequiredAttribute();
        public string ButtonName { get; set; }
    
        public RequiredIfButtonClickedAttribute(string buttonName)
        {
            ButtonName = buttonName;
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if ((value == null && !string.IsNullOrEmpty(HttpContext.Current.Request.Form[ButtonName])))
            {
                if (!_innerAttribute.IsValid(value))
                {
                    return new ValidationResult(this.ErrorMessage, new[] { validationContext.MemberName });
                }
            }
    
            return ValidationResult.Success;
        }
    
        #region IClientValidatable Members
    
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule() { ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), ValidationType = "requiredifbuttonclicked" };
            rule.ValidationParameters.Add("buttonname", ButtonName);
            yield return rule;
        }
    
        #endregion
    }
    

    客户端脚本:

    /// <reference path="jquery-1.4.4-vsdoc.js" />
    /// <reference path="jquery.validate.unobtrusive.js" />
    
    // When a button is clicked remove the clicked button class from all buttons and add it to the on that was clicked
    $(":submit").click(function () {
        $(":submit").removeClass('clickedButton');
        $(this).addClass('clickedButton');
    });
    
    $.validator.addMethod('requiredifbuttonclicked',
        function (value, element, parameters) {
    
            // if the condition is true, reuse the existing 
            // required field validator functionality
            if ($(".clickedButton").val("name") === parameters['buttonname'])
                return $.validator.methods.required.call(
                  this, value, element, parameters);
    
            return true;
        }
    );
    
    $.validator.unobtrusive.adapters.add(
        'requiredifbuttonclicked',
        ['buttonname'],
        function (options) {
            options.rules['requiredifbuttonclicked'] = {
                buttonname: options.params['buttonname']
            };
            options.messages['requiredifbuttonclicked'] = options.message;
    });
    

    并像这样使用它:

    [RequiredIfButtonClicked("myButtonName")]
    public string Name { get; set; }
    

    【讨论】:

    • 哇,如果可以的话,我会给你更多的答案,然后+1。
    • 为什么不内置这样的东西?与 ASP.net 无关。
    • 除了一些小改动之外,这非常完美。你应该说 prop("name") 而不是 val("name") 并且提交点击事件应该在文档就绪回调中。
    • 使用了带有 data dash 属性的锚标记以适应我的项目,因此我按照上面的建议将 val("name")/prop("name") 更改为 attr("data-name")。这个答案很好用。点赞!谢谢瑞恩!
    • 你怎么知道这是如何调用需要的方法呢? $.validator.methods.required.call(this, value, element, parameters) 四个参数? “这个”对象?无法找到有关该主题的任何好的文档。找到了这个,但它没有说明如何像你一样调用所需的方法。 jqueryvalidation.org/required-method
    【解决方案2】:

    您可以为每个提交按钮指定相同的名称和不同的值。然后在您的视图模型上有一个具有此字符串类型名称的属性。当表单被提交时,它的值将与被点击的按钮的值相匹配。现在您可以设计一个自定义验证器属性,用于装饰您的视图模型。在其 IsValid 实现中,您将获取视图模型的实例,并根据特殊属性的值执行验证。我知道这很难看,但是 DataAnnotations 对于简单的验证情况确实很有用,但是当您开始编写现实世界的应用程序时,您会意识到它们的局限性。

    我个人使用FluentValidation.NET,并且像这里描述的那样的场景实现起来非常简单。

    【讨论】:

    • 一见钟情!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    • 2010-09-24
    • 2015-02-26
    相关资源
    最近更新 更多