asp.net MVc 数据验证

来源:互联网 发布:外贸网站域名 编辑:程序博客网 时间:2024/04/29 18:54
 asp.net mvc 之 asp.net mvc 3.0 新特性之 Model:
  • 通过 Data Annotations 与 jQuery 的结合实现服务端和客户端的双重验证
  • 双重验证中,使客户端实现远程的异步验证
  • 自定义 Data Annotations 与 jQuery,以实现自定义的双重验证


示例
1、Model 中通过 Data Annotations 与 jQuery 的结合实现服务端和客户端的双重验证
Web.config
view sourceprint?
<configuration>
    <!--
        要实现服务端和客户端的双重验证,需要做如下配置,因为双重验证中的客户端验证需要依赖此配置
    -->
    <appSettings>
        <addkey="ClientValidationEnabled"value="true"/>
        <addkey="UnobtrusiveJavaScriptEnabled"value="true"/>
    </appSettings>
</configuration>

User.cs
view sourceprint?
/*
 * 在 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
{
    publicclass User
    {
        publicint ID { get;set; }
          
        [DisplayName("名字")]
        [Required(ErrorMessage ="名字不能为空")]
        publicstring Name { get; set; }
  
        [DisplayName("密码")]
        [Required(ErrorMessage ="密码不能为空")]
        publicstring Password { get; set; }
  
        [DisplayName("确认密码")]
        [Required(ErrorMessage ="确认密码不能为空")]
        [Compare("Password", ErrorMessage="两次密码输入不一致")]
        publicstring ConfirmPassword {get; set; }
  
        publicDateTime DateOfBirth { get;set; }
  
        // 请求时,允许此字段包含 HTML 标记
        [AllowHtml]
        publicstring Comment { get; set; }
    }
}

ValidationDemoController.cs
view sourceprint?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
  
using MVC30.Models;
  
namespace MVC30.Controllers
{
    publicclass ValidationDemoController : Controller
    {
        // 用于演示通过 Data Annotations 实现服务端和客户端的双重验证
        publicActionResult Validation_DataAnnotations()
        {
            var user =new User { ID = 1, Name ="webabcd", DateOfBirth =new DateTime(1980, 2, 14), Comment ="<b>mvp</b>" };
  
            returnView(new User());
        }
  
        [HttpPost]
        publicActionResult Validation_DataAnnotations(User user)
        {
            returnView(user);
        }
    }
}

Validation_DataAnnotations.cshtml
view sourceprint?
@model MVC30.Models.User
             
@{
    ViewBag.Title = "Validation_DataAnnotations";
}
  
<h2>ClientValidation</h2>
  
<!--
    通过 jQuery 实现客户端验证的逻辑,需要引用此 js
-->
<scriptsrc="@Url.Content("~/Scripts/jquery.validate.min.js")"type="text/javascript"></script>
<!--
    服务端验证与客户端验证的一一对应需要引用此 js
-->
<scriptsrc="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"type="text/javascript"></script>
  
@*
在 MVC3 中实现客户端验证,不需要添加以下代码
@{ Html.EnableClientValidation(); }
*@
  
@using (Html.BeginForm())
{
    <fieldset>
        <legend>User</legend>
        <divclass="editor-label">
            @Html.LabelFor(model => model.Name)
            (测试方法:空着文本框,然后提交)
        </div>
        <divclass="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>
        <p>
            <inputtype="submit"value="Create"/>
        </p>
    </fieldset>
}


2、Model 中通过 Data Annotations 与 jQuery 的结合实现服务端和客户端的双重验证,其中客户端可以实现远程的异步验证
User.cs
view sourceprint?
/*
 * 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
{
    publicclass User
    {
        publicint ID { get;set; }
          
        [DisplayName("名字")]
        [Required(ErrorMessage ="名字不能为空")]
        [Remote("CheckUserNameExists","ValidationDemo", ErrorMessage ="名字已存在")]
        publicstring Name { get; set; }
  
        [DisplayName("密码")]
        [Required(ErrorMessage ="密码不能为空")]
        publicstring Password { get; set; }
  
        [DisplayName("确认密码")]
        [Required(ErrorMessage ="确认密码不能为空")]
        [Compare("Password", ErrorMessage="两次密码输入不一致")]
        publicstring ConfirmPassword {get; set; }
  
        publicDateTime DateOfBirth { get;set; }
  
        // 请求时,允许此字段包含 HTML 标记
        [AllowHtml]
        publicstring Comment { get; set; }
    }
}

ValidationDemoController.cs
view sourceprint?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
  
using MVC30.Models;
  
namespace MVC30.Controllers
{
    publicclass ValidationDemoController : Controller
    {
        // 用于演示客户端的远程 ajax 异步验证
        publicActionResult Validation_Remote()
        {
            var user =new User { ID = 1, Name ="webabcd", DateOfBirth =new DateTime(1980, 2, 14), Comment ="<b>mvp</b>" };
  
            returnView(new User());
        }
  
        [HttpPost]
        publicActionResult Validation_Remote(User user)
        {
            returnView(user);
        }
  
        // 用于处理客户端的异步请求,测试时请使用字符串“webabcd”
        [HttpGet]
        publicActionResult CheckUserNameExists(stringname)
        {
            returnJson(name != "webabcd", JsonRequestBehavior.AllowGet);
        }
    }
}

Validation_Remote.cshtml
view sourceprint?
@model MVC30.Models.User
             
@{
    ViewBag.Title = "Validation_Remote";
}
  
<h2>ClientValidation</h2>
  
<scriptsrc="@Url.Content("~/Scripts/jquery.validate.min.js")"type="text/javascript"></script>
<scriptsrc="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"type="text/javascript"></script>
  
@using (Html.BeginForm())
{
    <fieldset>
        <legend>User</legend>
        <divclass="editor-label">
            @Html.LabelFor(model => model.Name)
            (测试方法:在文本框中输入“webabcd”)
        </div>
        <divclass="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>
        <p>
            <inputtype="submit"value="Create"/>
        </p>
    </fieldset>
}


3、Model 中使用更多的 Data Annotations 以及实现自定义的 Data Annotations 和自定义 jQuery 的相关逻辑
User.cs
view sourceprint?
/*
 * 如何使用更多的 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
{
    publicclass User
    {
        publicint ID { get;set; }
          
        [DisplayName("名字")]
        [Required(ErrorMessage ="名字不能为空")]
        [Remote("CheckUserNameExists","ValidationDemo", ErrorMessage ="名字已存在")]
        publicstring Name { get; set; }
  
        [DisplayName("密码")]
        [Required(ErrorMessage ="密码不能为空")]
        [Integer(ErrorMessage ="密码必须是整型")]
        publicstring Password { get; set; }
  
        [DisplayName("确认密码")]
        [Required(ErrorMessage ="确认密码不能为空")]
        [Compare("Password", ErrorMessage="两次密码输入不一致")]
        publicstring ConfirmPassword {get; set; }
  
        publicDateTime DateOfBirth { get;set; }
  
        // 请求时,允许此字段包含 HTML 标记
        [AllowHtml]
        publicstring Comment { get; set; }
    }
}

IntegerAttribute.cs
view sourceprint?
/*
 * 自定义 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() 方法,以实现客户端验证
    publicclass IntegerAttribute : ValidationAttribute, IClientValidatable
    {
        // 服务端验证逻辑,判断输入是否为整型
        publicoverride boolIsValid(objectvalue)
        {
            var number = Convert.ToString(value);
            returnRegex.IsMatch(number, @"^[0-9]+$");
        }
          
        // 客户端验证逻辑,需要结合客户端验证代码,详见 Validation_Custom.cshtml 文件
        publicIEnumerable<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");
  
            yieldreturn rule;
        }
    }
}

ValidationDemoController.cs
view sourceprint?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
  
using MVC30.Models;
  
namespace MVC30.Controllers
{
    publicclass ValidationDemoController : Controller
    {
        // 用于演示如何使用更多的 Data Annotations 来实现服务端和客户端的双重验证,以及如何自定义 Data Annotations 来实现服务端和客户端的双重验证
        publicActionResult Validation_Custom()
        {
            var user =new User { ID = 1, Name ="webabcd", DateOfBirth =new DateTime(1980, 2, 14), Comment ="<b>mvp</b>" };
  
            returnView(new User());
        }
  
        [HttpPost]
        publicActionResult Validation_Custom(User user)
        {
            returnView(user);
        }
    }
}

Validation_Custom.cshtml
view sourceprint?
@model MVC30.Models.User
             
@{
    ViewBag.Title = "ClientValidation";
}
  
<h2>ClientValidation</h2>
  
<scriptsrc="@Url.Content("~/Scripts/jquery.validate.min.js")"type="text/javascript"></script>
<scriptsrc="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"type="text/javascript"></script>
  
<scripttype="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>
        <divclass="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <divclass="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>
        <divclass="editor-label">
            @Html.LabelFor(model => model.Password)
            (测试方法:在文本框中输入非整型的字符串)
        </div>
        <divclass="editor-field">
            @Html.EditorFor(model => model.Password)
            @Html.ValidationMessageFor(model => model.Password)
        </div>
        <p>
            <inputtype="submit"value="Create"/>
        </p>
    </fieldset>
}