在ASP.NET MVC中使用自定义验证替换默认客户端验证

时间:2014-11-05 14:02:15

标签: asp.net asp.net-mvc validation asp.net-mvc-5 client-side-validation

我有一个包含DateTime属性的视图模型,我想使用自定义格式(仅限月份和年份,“MM.YYYY”)为其提供文本框:

public class MyModel {
  public DateTime? DateField {get; set;}
}

格式化TextBox的值很简单(使用格式字符串)。我还实现了一个自定义模型绑定器来进行转换,这很好。

我仍然遇到客户端验证问题:我可以实现派生自ValidationAttribute的自定义验证器,它实现IClientValidatable并设置相应的jquery.validate适配器等。

但是MVC仍然将“默认”验证属性data-val-date(除了我的自定义验证属性data-val-monthyeardate)添加到输入字段,因此默认检查仍然适用并且输入“MM.YYYY “被拒绝了。

有没有办法抑制数据类型的默认客户端验证并将其替换为自定义数据类型(而不是“添加”自定义数据类型)?

3 个答案:

答案 0 :(得分:3)

由于框架不允许您使用某些自定义属性覆盖实际类型,甚至覆盖特定类型的ModelMetadataProvider,因此您必须注册自己的全局ModelMetadataProvider愚弄验证者认为它实际上是string

类似的东西:

public class MyModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName)
    {
        if (attributes.OfType<ExcludeCharAttribute>().Any())
            modelType = typeof (String);

        return base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); ;
    }
}

使用以下方式注册:

ModelMetadataProviders.Current = new MyModelMetadataProvider();

尽管如此,由于核心问题是客户端问题,我会完全用客户端代码处理它。在monthyeardate适配器中,您可以强行删除date验证(如果您要共享monthyeardate代码,我可以提供一个示例)。

请参阅MSDN

答案 1 :(得分:2)

这很麻烦,但你能做的一件简单事就是添加:

$(function () {
    $.validator.methods.date = function () { return true; }; 
});

因此,默认数据-val-date始终返回true,同时触发自定义日期验证。

答案 2 :(得分:0)

我知道这有点老了,以防万一有人没有想到它(因为我还不能留下评论),为了增强@AlexC响应,你可以在该语句中添加验证。

例如,我使用moment.js进行日期验证(moment.js),这允许您添加自己的验证规则。

if (moment(a, "M/YYYY").isValid() || moment(a).isValid())
{
    return true;
}

这将检查它是否是一个常规日期,在这种情况下,如果日期在&#34; M / YYYY&#34;格式。如果其中一个为真,则接受验证。