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

在ASP.NET MVC中将默认客户端验证替换为自定义客户端验证,asp.net,asp.net-mvc,validation,asp.net-mvc-5,client-side-validation,Asp.net,Asp.net Mvc,Validation,Asp.net Mvc 5,Client Side Validation,我有一个包含DateTime属性的视图模型,我希望为其提供一个使用自定义格式的文本框(仅月份和年份,“MM.yyy”): 格式化文本框的值很容易(使用格式字符串)。我还实现了一个自定义模型绑定器来进行转换,效果很好 客户端验证仍然存在问题:我可以实现从ValidationAttribute派生的自定义验证器,该验证器实现IClientValidatable,并设置相应的jquery.validate适配器等 但是MVC仍然将“默认”验证属性data val date(除了我的自定义验证属性dat

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

格式化文本框的值很容易(使用格式字符串)。我还实现了一个自定义模型绑定器来进行转换,效果很好

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

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


是否有任何方法可以抑制数据类型的默认客户端验证,并将其替换为自定义类型(而不是“添加”自定义类型)?

这是一种很有技巧的方法,但您可以做的一件简单的事情是添加:

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

因此,在启动自定义日期验证时,默认数据val date始终返回true。

因为框架不允许您使用某些自定义属性覆盖实际类型,甚至不允许您覆盖特定类型的
ModelMetadataProvider
,您必须注册自己的全局
modelmataprovider
,这会让验证器误以为它实际上是一个
字符串

比如:

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); ;
    }
}
不过,由于核心问题是客户端问题,因此我将纯粹使用客户端代码来处理它。在
monthyeardate
适配器中,您可以强制删除
date
验证(如果您要共享
monthyeardate
代码,我可以提供一个示例)


请看

我知道这有点过时,为了防止有人不考虑(因为我还不能留下评论),为了增强@AlexC的响应,您可以在该语句中添加验证

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

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

这将检查它是否为常规日期,在本例中,该日期是否为“M/YYYY”格式。如果其中一个为真,则接受验证。

这将禁用页面中所有日期输入的日期验证。这是真的,我认为这可能不是可用的最佳解决方案。我很想看到更好的解决方案,这就是我一直在寻找的。谢谢你。你的
月初日期看起来怎么样?谢谢!与此同时,我还提出了第二个解决方案:在添加适配器时(使用
jQuery.validator.unobtrusive.adapters.add
),我添加了类似于
options.rules['date']=false的内容。这很好用。
ModelMetadataProviders.Current = new MyModelMetadataProvider();
if (moment(a, "M/YYYY").isValid() || moment(a).isValid())
{
    return true;
}