ASP.NET MVC验证组?

ASP.NET MVC验证组?,.net,asp.net-mvc,asp.net-mvc-3,validation,.net,Asp.net Mvc,Asp.net Mvc 3,Validation,我有一个表单,我想根据按下哪个提交按钮需要不同的字段。示例:如果按“提交”按钮1,则字段A为必填字段,但如果按“提交”按钮2,则仅字段B为必填字段。如果我仍然使用web表单,我会为每个按钮/验证器组合分配不同的“验证组”在MVC中有没有一种方法可以做到这一点,最好是在模型上添加数据注释?我更愿意使用单个解决方案实现客户端和服务器验证,但我会尽我所能 提前谢谢 您可以为每个提交按钮指定相同的名称和不同的值。然后在视图模型上有一个名称为string类型的属性。提交表单时,其值将与单击的按钮的值匹配。

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


提前谢谢

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


就我个人而言,这里描述的场景非常容易实现。

启用客户端验证的自定义验证属性如何(这样您就可以同时获得客户端和服务器验证)?下面的解决方案使用jQuery进行不引人注目的验证。要使用它,您需要为所有按钮指定特定的名称,并将该名称传递给validation属性。按钮还需要具有某种类型的值,以便可以发回(以便服务器端代码可以测试它,即
)。我还没有测试过这段代码,所以我不确定它是否已经用完了。您可能需要制作一些MOD:

模型的验证属性:


哇,很好的答案,如果可以的话,我会给你更多+1。为什么像这样的东西没有内置?它与ASP.net无关。除了几个小改动之外,它工作得非常好。你应该说prop(“name”)而不是val(“name”),提交点击事件应该在一个文档就绪回调中。使用了带有数据破折号属性的锚定标记以适合我的项目,因此我按照上面的建议将val(“name”)/prop(“name”)更改为attr(“数据名称”)。这个答案非常有效。向上投票!谢谢你,瑞安!您如何知道这是如何调用所需方法的?$。validator.methods.required.call(this,value,element,parameters)四个参数?“这个”对象是什么?没有找到任何关于这个主题的好文档。找到了这个,但它没有像您那样说明如何调用所需的方法。一见钟情!谢谢
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; }