我正在使用MVC5,其中包含一个包含以下字段的表单:
StudentType - Radio button
GradId - dropdown
HSYearofGradId - dropdown
CollegeStatusId - dropdown
根据这些字段,我想根据他们选择的内容在HSYearofGradId
上应用验证规则。例如,如果他们选择StudentType
A ,他们只会看到GradId
,并且只有当他们选择GradId
中的第三项时,他们才会看到HSYearofGradId
}。同样,如果他们选择StudentType
B ,他们会同时看到GradId
和HSYearofGradId
。这里的关键是StudentType
A 和 B 不同,因此错误消息应显示不同的值。
我有以下错误消息:You must select an option for your year of {0} in order to proceed."
我想用客户端的值替换{0}。
在单步执行JavaScript之后,我注意到我的字符串最初被替换,但后来被我设置的原始错误覆盖:You must select an option for your year of {0} in order to proceed. I noticed this in one validator's internals:
$。validator.format(message.replace(theregex, " {$ 1}"),rule.parameters);`将{0}更改为[object object]。
我使用以下问题作为参考: How to change MVC custom client-side validation error message at runtime using jQuery?
所以,我使用了MVC不引人注目的客户端验证功能。我创建了一个自定义验证属性,实现了IClientValidatable接口。 GetClientValidationRules方法如下所示:
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var modelClientValidationRule = new ModelClientValidationRule
{
ValidationType = "requiredif",
ErrorMessage = ErrorMessage
};
// rule.ValidationParameters["condition"] = "#" + Condition; // CSS Selector (won't work if applied to nested properties on a viewmodel)
// Attached to field
modelClientValidationRule.ValidationParameters.Add("property", Property);
modelClientValidationRule.ValidationParameters.Add("condition", Condition);
modelClientValidationRule.ValidationParameters.Add("minimum", Minimum);
modelClientValidationRule.ValidationParameters.Add("errormessage", ErrorMessage);
yield return modelClientValidationRule;
}
此验证属性应用于以下属性,如下所示:
[Display(Name = "College Student Status")]
[Integer(ErrorMessage = "You must select an option for College Student Status in order to proceed.")]
[RequiredIf("StudentType", "college", 1, ErrorMessage = "You must select an option for College Student Status in order to proceed.")]
public Nullable<int> CollegeStatusId { get; set; }
[Display(Name = "When will you graduate?")]
[Integer(ErrorMessage = "You must select an option for when will you graduate in order to proceed.")]
[RequiredIf("StudentType", "high school", 1, ErrorMessage = "You must select an option for when will you graduate in order to proceed.")]
public Nullable<int> GradId { get; set; }
[Display(Name = "HS Year")]
public string HighSchoolYear { get; set; }
// Choosing 3rd option for gradId
[Display(Name = "In which year did you graduate?")]
[Integer(ErrorMessage = "You must select an option for your year of graduation to proceed.")]
[RequiredIf("StudentType", "3", 1, ErrorMessage = "You must select an option for your year of {0} in order to proceed.")]
public Nullable<int> HSYearofGradId { get; set; }
我在.js文件中有客户端验证函数,如下所示:
jQuery.validator.addMethod('requiredif', function (value, element, params) {
var validator = this;
var conditionIsMet = false;
var propertyId = $(element).attr('data-val-requiredif-property');
var condition = $(element).attr('data-val-requiredif-condition');
var minimum = $(element).attr('data-val-requiredif-minimum');
var errorMessage = $(element).attr('data-val-requiredif-errormessage');
var errors = {};
var radioValue = $("input[name='" + propertyId + "']:checked").val();
if (propertyId === "StudentType") {
// i.e. high school
if (radioValue === condition) {
conditionIsMet = true;
}
}
else if (propertyId === "HighSchoolLocal") {
// what if not dropdown
if (value === "") {
// check if we are in no mode.
if (radioValue === condition) {
conditionIsMet = false;
} else {
if ($('#LocalBoroughId').is(':disabled')) {
conditionIsMet = false;
} else {
conditionIsMet = true;
}
}
}
}
//TODO: hardcoded value
if (element.id === "HSYearofGradId") {
if (parseInt($(element).val()) < parseInt(minimum)) {
var gradType;
if (radioValue === 'college') {
// TODO: error message is still wrong
gradType = "High School graduation";
} else {
gradType = "graduation";
}
errors[element.name] = $.validator.format(errorMessage, gradType);
$.validator.messages.requiredif = $.validator.format(errorMessage, gradType);
validator.showErrors(errors);
conditionIsMet = false;
} else {
conditionIsMet = true;
}
} else if (value) {
if (parseInt(value) < parseInt(minimum)) {
errors[element.name] = errorMessage;
validator.showErrors(errors);
conditionIsMet = false;
} else {
conditionIsMet = true;
}
}
return conditionIsMet; });
这是适配器:
jQuery.validator.unobtrusive.adapters.add('requiredif', {}, function (options) {
options.rules['requiredif'] = options.params;
if (options.message != null) {
options.messages['requiredif'] = options.message;
}});
修改 我想我发现了这个问题。 jquery.validate.js中有一些方法可以获取给定元素名称和验证方法的自定义消息。所有参数都传递给以下方法。我注意到列表中的第一个错误被传回。此外,第一个错误恰好是实体上设置的原始错误。
findDefined: function() {
for (var i = 0; i < arguments.length; i++) {
if ( arguments[i] !== undefined ) {
return arguments[i];
}
}
临时解决方案:
我不知道这是不是最好的方法,但它确实有效。
this.settings.messages["FIELDNAME"]["VALIDATION_NAME"] = "NEW MESSAGE"
就我而言,我做了以下事情:
errors[element.name] = $.validator.format(errorMessage, gradType);
$.validator.messages.requiredif = $.validator.format(errorMessage, gradType);
this.settings.messages["HSYearofGradId"]["requiredif"] = $.validator.messages.requiredif;