我有一个表单,我想根据按下的提交按钮需要不同的字段。示例:如果按下“提交按钮1”,则需要字段A,但如果按“提交”按钮2,则只需要字段B.如果我仍在使用Web表单,则会为每个按钮/验证器组合分配不同的“验证组”。 有没有办法在MVC中执行此操作,最好是在模型上使用数据注释?我更倾向于使用单个解决方案实现客户端和服务器验证,但我会采取我能得到的...
提前致谢!
答案 0 :(得分:21)
启用客户端验证的自定义验证属性如何(因此您同时获得客户端和服务器验证)?下面的解决方案使用jQuery不显眼的验证。要使用此功能,您需要为所有按钮指定特定名称,并将名称传递给验证属性。该按钮还需要具有某种值,以便可以回发(因此服务器端代码可以对其进行测试,即<input type="submit" name="myButton" value="1" />
)。我没有测试过这段代码,所以我不确定它是否已经开箱即用。您可能需要制作一些mod:
模型的验证属性:
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 :(得分:3)
您可以为每个提交按钮和不同的值指定相同的名称。然后在视图模型上有一个具有此类型string类型的属性。提交表单时,其值将与单击的按钮的值匹配。现在,您可以设计一个自定义验证器属性,用于装饰您的视图模型。在其IsValid实现中,您将获取视图模型的实例,并根据您将执行验证的特殊属性的值。我知道,这很难看,但DataAnnotations对于简单的验证情况非常有用,但是当你开始编写真实世界的应用程序时,你会发现它们的局限性。
就个人而言,我使用FluentValidation.NET,这里描述的场景非常简单,无法实现。