这是简化模型:
public class Person {
public int Id;
public string Name;
}
public class Task {
public int Id;
public int PersonId;
public DateTime StartDate;
[GreaterThan("StartDate")]
public DateTime EndDate;
}
要验证EndDate> = StartDate,我会编写一般 GreaterThanAttribute 。服务器端是微不足道的,但我在客户端验证方面存在问题。
我的GreaterThanAttribute从构造函数中获取了另一个属性(例如:“StartDate”),然后我将此其他属性名称作为验证规则传递给javascript。但它不会起作用,因为JS不会找到这个元素,因为MVC会渲染&将其命名为“Task.StartDate”,而不是“StartDate”。
我的问题是,如何获取控制器用于在IClientValidatable.GetClientValidationRules()中呈现我的模型的前缀?
由于
答案 0 :(得分:2)
以下是您如何实施它:
public class GreaterThanAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _otherProperty;
public GreaterThanAttribute(string otherProperty)
{
_otherProperty = otherProperty;
}
public override string FormatErrorMessage(string name)
{
return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name, _otherProperty);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(_otherProperty);
if (property == null)
{
return new ValidationResult(
string.Format(
CultureInfo.CurrentCulture,
"unknown property {0}",
_otherProperty
)
);
}
var otherValue = (DateTime)property.GetValue(validationContext.ObjectInstance, null);
var thisValue = (DateTime)value;
if (thisValue <= otherValue)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return null;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationType = "greaterthandate";
rule.ValidationParameters["other"] = "*." + _otherProperty;
yield return rule;
}
}
并在客户端:
(function ($) {
var getModelPrefix = function (fieldName) {
return fieldName.substr(0, fieldName.lastIndexOf('.') + 1);
};
var appendModelPrefix = function (value, prefix) {
if (value.indexOf('*.') === 0) {
value = value.replace('*.', prefix);
}
return value;
};
$.validator.unobtrusive.adapters.add('greaterthandate', ['other'], function (options) {
var prefix = getModelPrefix(options.element.name),
other = options.params.other,
fullOtherName = appendModelPrefix(other, prefix),
element = $(options.form).find(':input[name=' + fullOtherName + ']')[0];
options.rules['greaterThanDate'] = element;
if (options.message) {
options.messages['greaterThanDate'] = options.message;
}
});
$.validator.addMethod('greaterThanDate', function (value, element, params) {
var otherDate = $(params).val();
var thisDate = value;
// TODO: put your custom date comparison implementation here between
// the 2 values. Be careful here. Javascript date handling is culture dependent
// so you might need to account for that when building your js Date instances
return false;
}, '');
})(jQuery);
答案 1 :(得分:0)
这已经完成了。我建议你使用FoolProof验证。如果你不想,你至少可以查看他们的源代码。这是一个link