代码改变世界

ASP.NET MVC 扩展之自定义模型验证,客户端 + 服务器端

2012-06-26 20:56  音乐让我说  阅读(654)  评论(0编辑  收藏  举报

代码大部分来自 Artech 大哥的:ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)

其中我修改了日期格式(从 dd/MM/yyyy 修改为 yyyy-MM-dd),以下我贴出我修改后的代码:

首先,贴出核心验证 Attribute:AgeRangeAttribute

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace DearBruce.CustomClientValidationDemo.MvcUI.Extensions
{
    public class AgeRangeAttribute : RangeAttribute, IClientValidatable
    {
        public AgeRangeAttribute(int minimum, int maximum)
            : base(minimum, maximum)
        { }

        public override bool IsValid(object value)
        {
            DateTime birthDate;
            if (value == null || !DateTime.TryParse(value.ToString(), out birthDate))
            {
                return false;
            }
            DateTime age = new DateTime(DateTime.Now.Ticks - birthDate.Ticks);
            return age.Year >= (int)this.Minimum && age.Year <= (int)this.Maximum;
        }

        //public override string FormatErrorMessage(string name)
        //{
        //    return base.FormatErrorMessage("年龄");
        //}

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            ModelClientValidationRule validationRule = new ModelClientValidationRule(){ ValidationType = "agerange", ErrorMessage= FormatErrorMessage(metadata.DisplayName)};
            validationRule.ValidationParameters.Add("currentdate",DateTime.Today.ToString("yyyy-MM-dd"));
            validationRule.ValidationParameters.Add("minage",this.Minimum);
            validationRule.ValidationParameters.Add("maxage",this.Maximum);
            yield return validationRule;
        }
    }
}


Person 实体:

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using DearBruce.CustomClientValidationDemo.MvcUI.Extensions;

namespace DearBruce.CustomClientValidationDemo.MvcUI.Models
{
    public class Person
    {
        [DisplayName("姓名")]
        public string Name { get; set; }

        [AgeRange(18, 30, ErrorMessage = "{0}必须在{1}和{2}之间!")]
        [DisplayName("出生日期")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
        public DateTime? BirthDate { get; set; }
    }
}


HomeController:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new Person { BirthDate = DateTime.Today, Name = "Foo" });
        }

        [HttpPost]
        public ActionResult Index(Person person)
        {
            return View(person);
        }
    }

Index.cshtml:

@{
    ViewBag.Title = "主页";
}

@model DearBruce.CustomClientValidationDemo.MvcUI.Models.Person
@using (Html.BeginForm())
{     
    @Html.EditorForModel()
    <br />
    <p>
        <input type="submit" value="Save" />
    </p>
    
    @*<p>
        请输入日期:<input type="text" id="txtDateOfBirth" onblur="validateDateOfBirth()"/>
    </p>*@
}

dearbruce.jquery.validate.cutom-validation.js:

jQuery.validator.addMethod("agerange",
function (value, element, params)
{
    var minAge = params.minage;
    var maxAge = params.maxage;

    var literalCurrentDate = params.currentdate;
    var literalBirthDate = value;
    var literalCurrentDates = literalCurrentDate.split('-');
    var literalBirthDates = literalBirthDate.split('-');

    var birthDate = new Date(literalBirthDates[0], literalBirthDates[1], literalBirthDates[2]);
    if (birthDate == undefined || isNaN(birthDate))
    {
        // alert("日期格式错误!"); // 注意:这里千万不要弹出提示,因为用户每输入一个字符,就会弹出
        // 用户体验就会非常差
        return false;
    }
    var currentDate = new Date(literalCurrentDates[0], literalCurrentDates[1], literalCurrentDates[2]);
    var age = currentDate.getFullYear() - birthDate.getFullYear();
    return age >= minAge && age <= maxAge
});

jQuery.validator.unobtrusive.adapters.add("agerange", ["currentdate", "minage", "maxage"], function (options)
{
    options.rules["agerange"] = {
        currentdate: options.params.currentdate,
        minage: options.params.minage,
        maxage: options.params.maxage
    };
    options.messages["agerange"] = options.message;
});

 

 

谢谢浏览!