对自定义属性执行客户端验证

Posted

技术标签:

【中文标题】对自定义属性执行客户端验证【英文标题】:Perform client side validation for custom attribute 【发布时间】:2011-06-12 10:37:26 【问题描述】:

我创建了一个自定义验证属性:

public class FutureDateAttribute : ValidationAttribute
    
        public override bool IsValid(object value) 
        
            if (value == null|| (DateTime)value < DateTime.Now)
                return false;

            return true;
        

    

如何使用 jquery 让它在客户端也能工作?

【问题讨论】:

【参考方案1】:

以下是如何继续:

首先定义自定义验证属性:

public class FutureDateAttribute : ValidationAttribute, IClientValidatable

    public override bool IsValid(object value)
    
        if (value == null || (DateTime)value < DateTime.Now)
            return false;

        return true;
    

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    
        yield return new ModelClientValidationRule
        
            ErrorMessage = this.ErrorMessage,
            ValidationType = "futuredate"
        ;
    

注意它是如何实现IClientValidatable 的。接下来我们编写我们的模型:

public class MyViewModel

    [FutureDate(ErrorMessage = "Should be in the future")]
    public DateTime Date  get; set; 

然后是控制器:

public class HomeController : Controller

    public ActionResult Index()
    
        return View(new MyViewModel
        
            // intentionally put in the past
            Date = DateTime.Now.AddDays(-1)
        );
    

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    
        return View(model);
    

最后是一个视图:

@using (html.BeginForm())

    @Html.LabelFor(x => x.Date)
    @Html.TextBoxFor(x => x.Date)
    @Html.ValidationMessageFor(x => x.Date)
    <input type="submit" value="OK" />

魔法发生的最后一部分是定义自定义适配器:

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    // we add a custom jquery validation method
    jQuery.validator.addMethod('greaterThan', function (value, element, params) 
        if (!/Invalid|NaN/.test(new Date(value))) 
            return new Date(value) > new Date($(params).val());
        
        return isNaN(value) && isNaN($(params).val()) || (parseFloat(value) > parseFloat($(params).val()));
    , '');

    // and an unobtrusive adapter
    jQuery.validator.unobtrusive.adapters.add('futuredate',  , function (options) 
        options.rules['greaterThan'] = true;
        options.messages['greaterThan'] = options.message;
    );
</script>

【讨论】:

@raklos,这将取决于浏览器和服务器的本地化设置。如果您有差异,事情会变得复杂,因为一种格式可以通过客户端验证但不能通过服务器验证,反之亦然。此外,您还可以决定希望日期采用什么格式。 啊啊我可以亲你一下 很好的例子。为了让客户端为我工作,适配器需要将return new Date(value) &gt; new Date($(params).val()); 更改为return new Date(value) &gt; new Date();new Date($(params).val())new Date() 我在让客户端使用 Ajax.BeginForm 而不是 Html.BeginForm 工作时遇到问题。在这种情况下会有问题吗? @kehrk,是的,如果您使用的是 ASP.NET 4 包,最好将其作为某个包的一部分。【参考方案2】:

您的问题被提出后过了一段时间,但如果您仍然喜欢元数据,并且您仍然愿意接受简化的替代方案,您可以使用以下注释解决您的问题:

[Required]
[AssertThat("Date > Now()")]
public DateTime? Date  get; set; 

它适用于服务器和客户端,开箱即用。有关更多详细信息,请查看ExpressiveAnnotations library。

【讨论】:

你的图书馆拯救了我的一天。使用非常简单,非常有用。谢谢

以上是关于对自定义属性执行客户端验证的主要内容,如果未能解决你的问题,请参考以下文章

使用数据注释的依赖属性的自定义模型验证

自定义验证----required属性

iOS https请求对自签名证书忽略

在 Asp.net Core MVC 中定义自定义客户端验证规则

具有客户端验证的自定义数据注释验证属性

Apollo 客户端:如何对自定义事件执行查询