我正在努力为半复杂场景完成服务器-客户端验证解决方案。我有一个核心类型叫做DateRange
:
public class DateRange {
public DateRange (DateTime? start, DateTime? end) { ... }
public DateTime? Start { get; private set; }
public DateTime? End { get; private set; }
}
我有一个视图模型,例如:
public class MyViewModel {
public DateRange Period { get; set; }
}
我有一个 %mvcproject%\Views\Shared\EditorTemplates\DateRange.cshtml 像:
@model MyCore.DateRange
@Html.Editor("Start", "Date")
@Html.Editor("End", "Date")
我还有一个DateRangeModelBinder
将两个表单输入绑定到DateRange
属性中。我遇到的问题是DateRangeRequiredAttribute
:
public class DateRangeRequired : ValidationAttribute, IClientValidatable,
IMetadataAware
{
private const string DefaultErrorMessage =
"{0} is required.";
public DateRangeRequired(bool endIsRequired = true)
: base(() => DefaultErrorMessage)
{
EndIsRequired = endIsRequired;
}
public bool EndIsRequired { get; set; }
public override bool IsValid(object value)
{
if (value == null)
{
return false;
}
if (!value.GetType().IsAssignableFrom(typeof(DateRange)))
{
throw new ArgumentException("Value is not a DateRange.");
}
var dateRange = value as DateRange;
return (dateRange.Start.HasValue && !EndIsRequired) ||
(dateRange.Start.HasValue && dateRange.End.HasValue && EndIsRequired);
}
public override string FormatErrorMessage(string name)
{
return string.Format(CultureInfo.CurrentCulture, ErrorMessageString, name);
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "daterangerequired"
};
rule.ValidationParameters.Add("endisrequired", EndIsRequired.ToString().ToLower());
yield return rule;
}
public void OnMetadataCreated(ModelMetadata metadata)
{
metadata.DataTypeName = "DateRange";
}
}
我无法让它连接到两个输入。由于拆分输入,几乎就像需要ValidatorTemplate
与 EditorTemplate 配对一样。有任何想法吗?让我知道是否需要进一步澄清。