【问题标题】: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 让它在客户端也能工作?

【问题讨论】:

    标签: jquery asp.net-mvc validation asp.net-mvc-3 razor


    【解决方案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。

    【讨论】:

    • 你的图书馆拯救了我的一天。使用非常简单,非常有用。谢谢
    猜你喜欢
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 2014-03-27
    • 2011-09-09
    • 2012-03-06
    • 2014-11-03
    • 2013-11-12
    • 2011-08-05
    相关资源
    最近更新 更多