asp.net MVc 数据验证

来源:岁月联盟 编辑:exp 时间:2011-10-11

 

asp.net mvc 之asp.net mvc 3.0 新特性之Model:

通过Data Annotations 与jQuery 的结合实现服务端和客户端的双重验证

双重验证中,使客户端实现远程的异步验证

自定义Data Annotations 与jQuery,以实现自定义的双重验证

 

 

示例

1、Model 中通过Data Annotations 与jQuery 的结合实现服务端和客户端的双重验证

Web.config

 

<configuration>

    <!--

        要实现服务端和客户端的双重验证,需要做如下配置,因为双重验证中的客户端验证需要依赖此配置

    -->

    <appSettings>

        <add key="ClientValidationEnabled" value="true"/>

        <add key="UnobtrusiveJavaScriptEnabled" value="true"/>

    </appSettings>

</configuration>

User.cs

 

/*

 * 在asp.net mvc 3.0 中支持通过Data Annotations 来实现服务端和客户端的双重验证,需要jQuery 的支持

 * 所有Data Annotations 相关的Attribute 直接用类视图看System.ComponentModel.DataAnnotations 就行了,详细说明以前写过好多遍了,这里就不重复了

 * 另外System.Web.Mvc 下有一些新增的Data Annotations

 */

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

using System.ComponentModel;

using System.ComponentModel.DataAnnotations;

using System.Web.Mvc;

 

namespace MVC30.Models

{

    public class User

    {

        public int ID { get; set; }

         

        [DisplayName("名字")]

        [Required(ErrorMessage = "名字不能为空")]

        public string Name { get; set; }

 

        [DisplayName("密码")]

        [Required(ErrorMessage = "密码不能为空")]

        public string Password { get; set; }

 

        [DisplayName("确认密码")]

        [Required(ErrorMessage = "确认密码不能为空")]

        [Compare("Password", ErrorMessage="两次密码输入不一致")]

        public string ConfirmPassword { get; set; }

 

        public DateTime DateOfBirth { get; set; }

 

        // 请求时,允许此字段包含HTML 标记

        [AllowHtml]

        public string Comment { get; set; }

    }

}

ValidationDemoController.cs

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

 

using MVC30.Models;

 

namespace MVC30.Controllers

{

    public class ValidationDemoController : Controller

    {

        // 用于演示通过Data Annotations 实现服务端和客户端的双重验证

        public ActionResult Validation_DataAnnotations()

        {

            var user = new User { ID = 1, Name = "webabcd", DateOfBirth = new DateTime(1980, 2, 14), Comment = "<b>mvp</b>" };

 

            return View(new User());

        }

 

        [HttpPost]

        public ActionResult Validation_DataAnnotations(User user)

        {

            return View(user);

        }

    }

}

Validation_DataAnnotations.cshtml

 

@model MVC30.Models.User

            

@{

    ViewBag.Title = "Validation_DataAnnotations";

}

 

<h2>ClientValidation</h2>

 

<!--

    通过jQuery 实现客户端验证的逻辑,需要引用此js

-->

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>

<!--

    服务端验证与客户端验证的一一对应需要引用此js

-->

<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

 

@*

在MVC3 中实现客户端验证,不需要添加以下代码

@{ Html.EnableClientValidation(); }

*@

 

@using (Html.BeginForm())

{

    <fieldset>

        <legend>User</legend>

        <div class="editor-label">

            @Html.LabelFor(model => model.Name)

            (测试方法:空着文本框,然后提交)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Name)

            @Html.ValidationMessageFor(model => model.Name)

        </div>

        <p>

            <input type="submit" value="Create" />

        </p>

    </fieldset>

}

 

2、Model 中通过Data Annotations 与jQuery 的结合实现服务端和客户端的双重验证,其中客户端可以实现远程的异步验证

User.cs

 

/*

 * System.Web.Mvc.Remote(string action, string controller) - 让客户端可以通过ajax 的方式远程验证

 *     action - 实现验证逻辑的action,即处理客户端的异步请求的action

 *     controller - 实现验证逻辑的controller,即处理客户端的异步请求的controller

 */

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

using System.ComponentModel;

using System.ComponentModel.DataAnnotations;

using System.Web.Mvc;

 

namespace MVC30.Models

{

    public class User

    {

        public int ID { get; set; }

         

        [DisplayName("名字")]

        [Required(ErrorMessage = "名字不能为空")]

        [Remote("CheckUserNameExists", "ValidationDemo", ErrorMessage = "名字已存在")]

        public string Name { get; set; }

 

        [DisplayName("密码")]

        [Required(ErrorMessage = "密码不能为空")]

        public string Password { get; set; }

 

        [DisplayName("确认密码")]

        [Required(ErrorMessage = "确认密码不能为空")]

        [Compare("Password", ErrorMessage="两次密码输入不一致")]

        public string ConfirmPassword { get; set; }

 

        public DateTime DateOfBirth { get; set; }

 

        // 请求时,允许此字段包含HTML 标记

        [AllowHtml]

        public string Comment { get; set; }

    }

}

ValidationDemoController.cs

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

 

using MVC30.Models;

 

namespace MVC30.Controllers

{

    public class ValidationDemoController : Controller

    {

        // 用于演示客户端的远程ajax 异步验证

        public ActionResult Validation_Remote()

        {

            var user = new User { ID = 1, Name = "webabcd", DateOfBirth = new DateTime(1980, 2, 14), Comment = "<b>mvp</b>" };

 

            return View(new User());

        }

 

        [HttpPost]

        public ActionResult Validation_Remote(User user)

        {

            return View(user);

        }

 

        // 用于处理客户端的异步请求,测试时请使用字符串“webabcd”

        [HttpGet]

        public ActionResult CheckUserNameExists(string name)

        {

            return Json(name != "webabcd", JsonRequestBehavior.AllowGet);

        }

    }

}

Validation_Remote.cshtml

 

@model MVC30.Models.User

            

@{

    ViewBag.Title = "Validation_Remote";

}

 

<h2>ClientValidation</h2>

 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>

<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

 

@using (Html.BeginForm())

{

    <fieldset>

        <legend>User</legend>

        <div class="editor-label">

            @Html.LabelFor(model => model.Name)

            (测试方法:在文本框中输入“webabcd”)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Name)

            @Html.ValidationMessageFor(model => model.Name)

        </div>

        <p>

            <input type="submit" value="Create" />

        </p>

    </fieldset>

}

 

3、Model 中使用更多的Data Annotations 以及实现自定义的Data Annotations 和自定义jQuery 的相关逻辑

User.cs

 

/*

 * 如何使用更多的Data Annotation

 *     1、在“Tools”中选择“Extension Manager”(安装NuGet 后会有此选项)

 *     2、搜索“DataAnnotationsExtensions”,然后安装“DataAnnotationsExtensions.MVC3”项目

 *     3、之后就可以使用此项目所支持的多个新的Data Annotation

 * 如何自定义Data Annotation

 *     详见:IntegerAttribute.cs

 */

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

using System.ComponentModel;

using System.ComponentModel.DataAnnotations;

using System.Web.Mvc;

 

namespace MVC30.Models

{

    public class User

    {

        public int ID { get; set; }

         

        [DisplayName("名字")]

        [Required(ErrorMessage = "名字不能为空")]

        [Remote("CheckUserNameExists", "ValidationDemo", ErrorMessage = "名字已存在")]

        public string Name { get; set; }

 

        [DisplayName("密码")]

        [Required(ErrorMessage = "密码不能为空")]

        [Integer(ErrorMessage = "密码必须是整型")]

        public string Password { get; set; }

 

        [DisplayName("确认密码")]

        [Required(ErrorMessage = "确认密码不能为空")]

        [Compare("Password", ErrorMessage="两次密码输入不一致")]

        public string ConfirmPassword { get; set; }

 

        public DateTime DateOfBirth { get; set; }

 

        // 请求时,允许此字段包含HTML 标记

        [AllowHtml]

        public string Comment { get; set; }

    }

}

IntegerAttribute.cs

 

/*

 * 自定义Data Annotation,以实现与jQuery 结合的客户端和服务端双重验证

 */

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

using System.ComponentModel.DataAnnotations;

using System.Text.RegularExpressions;

using System.Web.Mvc;

 

namespace MVC30.Models

{

    // 继承ValidationAttribute 抽象类,重写IsValid() 方法,以实现服务端验证

    // 实现IClientValidatable 接口的GetClientValidationRules() 方法,以实现客户端验证

    public class IntegerAttribute : ValidationAttribute, IClientValidatable

    {

        // 服务端验证逻辑,判断输入是否为整型

        public override bool IsValid(object value)

        {

            var number = Convert.ToString(value);

            return Regex.IsMatch(number, @"^[0-9]+$");

        }

         

        // 客户端验证逻辑,需要结合客户端验证代码,详见Validation_Custom.cshtml 文件

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)

        {

            var rule = new ModelClientValidationRule

            {

                ErrorMessage = this.ErrorMessage,

 

                // ValidationType - 指定一个key(字符串),该key 用于关联服务端验证逻辑与客户端验证逻辑。注:这个key 必须都是由小写字母组成

                ValidationType = "isinteger"

            };

 

            // 向客户端验证代码传递参数

            rule.ValidationParameters.Add("param1", "value1");

            rule.ValidationParameters.Add("param2", "value2");

 

            yield return rule;

        }

    }

}

ValidationDemoController.cs

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Mvc;

 

using MVC30.Models;

 

namespace MVC30.Controllers

{

    public class ValidationDemoController : Controller

    {

        // 用于演示如何使用更多的Data Annotations 来实现服务端和客户端的双重验证,以及如何自定义Data Annotations 来实现服务端和客户端的双重验证

        public ActionResult Validation_Custom()

        {

            var user = new User { ID = 1, Name = "webabcd", DateOfBirth = new DateTime(1980, 2, 14), Comment = "<b>mvp</b>" };

 

            return View(new User());

        }

 

        [HttpPost]

        public ActionResult Validation_Custom(User user)

        {

            return View(user);

        }

    }

}

Validation_Custom.cshtml

 

@model MVC30.Models.User

            

@{

    ViewBag.Title = "ClientValidation";

}

 

<h2>ClientValidation</h2>

 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>

<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

 

<script type="text/javascript">

 

    // 客户端验证逻辑,判断输入是否为整型

    jQuery.validator.addMethod(

        'checkInteger',

        function (value, element) {

            var reg = new RegExp("^[0-9]+$");

            return (reg.test(value));

        }

    );

 

    // 将客户端验证逻辑通过ValidationType 与服务端的相关验证逻辑结合起来

    jQuery.validator.unobtrusive.adapters.add(

        'isinteger', // ValidationType,必须全为小写

        ['param1', 'param2'], // 接收ModelClientValidationRule 中的参数信息

        function (options) {

            options.rules['checkInteger'] = true; // 启用名为checkInteger 的客户端验证逻辑

            options.messages['checkInteger'] = options.message; // 发生验证错误后的显示信息

            var param1 = options.params.param1; // ModelClientValidationRule 中的参数信息

            var param2 = options.params.param2; // ModelClientValidationRule 中的参数信息

            alert(param1 + " " + param2);

        }

    );

 

</script>

 

@using (Html.BeginForm())

{

    <fieldset>

        <legend>User</legend>

        <div class="editor-label">

            @Html.LabelFor(model => model.Name)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Name)

            @Html.ValidationMessageFor(model => model.Name)

        </div>

        <div class="editor-label">

            @Html.LabelFor(model => model.Password)

            (测试方法:在文本框中输入非整型的字符串)

        </div>

        <div class="editor-field">

            @Html.EditorFor(model => model.Password)

            @Html.ValidationMessageFor(model => model.Password)

        </div>

        <p>

            <input type="submit" value="Create" />

        </p>

    </fieldset>

}