在Asp.net MVC 中,View中我们仍然需要对提交的表单进行验证。通常验证分为客户端验证,服务端验证。
客户端验证,我们可以使用JQuery validation plugin,服务端验证,除了使用ModelState属性显示错误信息到
View,还可以使用Fluent Validation for .NET,一个小巧的.net验证框架,使用fluent的接口和lambda表达式对
你的业务对象构建验证规则。而且也有对应的MVC扩展。
     我们首先增加一个验证UserEntity的验证类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DemoMVCForm.Models;
using FluentValidation;
using FluentValidation.Validators;

namespace DemoMVCForm
{
    /// <summary>
    /// UserValidation
    /// </summary>
    /// <remark>Author : PetterLiu 2009-02-1515:54  http://wintersun.cnblogs.com </remark>
    public class UserValidation : AbstractValidator<UserEntity>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="UserValidation"/> class.
        /// </summary>
        /// <remark>Author : PetterLiu 2009-02-1515:54  http://wintersun.cnblogs.com </remark>
        public UserValidation()
        {
            RuleFor(u => u.UserName).NotEmpty();
            RuleFor(u => u.UserName).Length(5, 16);
            RuleFor(u => u.Password).NotEmpty().WithMessage("必须输入密码");
            RuleFor(u => u.Email).NotEmpty();
            RuleFor(u => u.Email).EmailAddress();
            RuleFor(u => u.Url).Url();
            RuleFor(u => u.PassportID).NotEmpty();
        }
    }

    /// <summary>
    ///  UrlValidationRule<T>
    /// </summary>
    /// <typeparam name="T">T</typeparam>
    /// <remark>Author : PetterLiu 2009-02-1515:54  http://wintersun.cnblogs.com </remark>
    public class UrlValidationRule<T> : RegularExpressionValidator<T>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="UrlValidationRule&lt;T&gt;"/> class.
        /// </summary>
        /// <remark>Author : PetterLiu 2009-02-1515:54  http://wintersun.cnblogs.com </remark>
        public UrlValidationRule()
            : base(@"^http\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?$")
        {

        }
    }

    /// <summary>
    /// UrlValidationExtension
    /// </summary>
    /// <remark>Author : PetterLiu 2009-02-1515:54  http://wintersun.cnblogs.com </remark>
    public static class UrlValidationExtension
    {
        public static IRuleBuilderOptions<T, string> Url<T>(this IRuleBuilder<T, string> ruleBuilder)
        {
            return ruleBuilder.SetValidator(new UrlValidationRule<T>());
        }
    }
}

看上增加了服务端验证规则多么简单的代码,比较直观。后又增加一个验证URL的规则,用于验证输入的URL。
接着来看,如何使用它:
/// <summary>
/// Registers the specified user.
/// </summary>
/// <param name="user">The user.</param>
/// <returns></returns>
/// <remark>Author : PetterLiu 2009-02-1515:56  http://wintersun.cnblogs.com </remark>
public JsonResult Register(UserEntity user)
{
    UserValidation userValidation = new UserValidation();
    ValidationResult validationResult = userValidation.Validate(user);

    //add error state information to ModelState.
    validationResult.AddToModelState(ModelState, "user");

    bool validationSucceeded = validationResult.IsValid;
    IList<ValidationFailure> failures = validationResult.Errors;
   
    //return result for json format.
    return Json(failures);
}
通过扩展的AddToModelState方法,能让验证的错误信息返回VIEW,但实际上如果没有使用Html.ValidationMessage,
也不需要这个方法了。看实际情况选择了。最后把验证后的结果对象:ValidationFarilure通过Json格式返回。
好,来看VIEW:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Demo</title>
    <style type="text/css">
        #inputArea
        {
            font-family: Arial, Sans-Serif;
        }
        #inputArea input, #inputArea textarea
        {
            font-family: Arial, Sans-Serif;
            margin-bottom: 5px;
            padding: 1px;
            border: solid 1px #85b1de;
        }
    </style>
    <link href="http://www.cnblogs.com/Content/Site.css" rel="stylesheet" type="text/css" />

    <script src="http://www.cnblogs.com/Scripts/jquery-1.3.1.js" type="text/javascript"></script>

    <script src="http://www.cnblogs.com/Scripts/jquery.validate.js" type="text/javascript"></script>

    <script src="http://www.cnblogs.com/Scripts/jquery.form.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(document).ready(function() {
            function ProcessJson(data) {
                var ret = "服务器返回验证结果:\n"
                for (key in data) {
                    ret += data[key].ErrorMessage;
                    ret += "\n";
                }
                alert(ret);
            }
            jQuery.validator.addMethod("usernamecheck", function(value, element) {
                return this.optional(element) || /^[a-zA-Z][a-zA-Z0-9_]{4,15}$/.test(value);
            }, "5-16位字母开头,允许字母数字下划线")

            jQuery.validator.addMethod("ppIdcheck", function(value, element) {
                return this.optional(element) || /^[1-9]([0-9]{14}|[0-9]{17})$/.test(value);
            }, "请输入正确的身份证号码(15-18位)")

            $("#form-sign-up").validate({
                rules: {
                    password: {required: true,usernamecheck: ""},
                    confirm_password: {required: true,minlength: 8,equalTo: "#password"},
                    username: {
                        required: true,
                        remote: '<%=Url.Action("IsLoginAvailable", "FormDemo") %>'
                    },
                    passportId:
                    {
                        required: true,
                        ppIdcheck: ""
                    }
                },
                messages: {
                        confirm_password: {
                        required: "请填写一个密码",
                        minLength: "长度必须8个字符",
                        equalTo: "请输入与上面相同的密码"
                    },
                    username: {
                        required: "请输入用户名",
                        remote: jQuery.format("{0} 已经有人用了")
                    },
                    checkbox11:
                    {
                        required: "请打勾"
                    }

                },
                // set this class to error-labels to indicate valid fields 
                success: function(label) {
                    // set   as text for IE 
                    label.html(" ").addClass("checked");
                },
                submitHandler: function(form) {
                    var formoption = {
                        dataType: "json",
                        url: '<%=Url.Action("Register", "FormDemo")%>',
                        type: "post",
                        success: ProcessJson  // post-submit callback 
                    };
                    $(form).ajaxSubmit(formoption);

                } 
            });
        });
    </script>

</head>
<body>
    <form method="post" id="form-sign-up">
    <h1>
        Demo表单</h1>
    <table id="inputArea">
        <tr>
            <td>
                用户名 (试试输入 Petter):
            </td>
            <td>
                <input type="text" name="username" id="username" />
            </td>
        </tr>
        <tr>
            <td>
                Email:
            </td>
            <td>
                <input type="text" name="email" id="email" class="required email" />
            </td>
        </tr>
        <tr>
            <td>
                Url:
            </td>
            <td>
                <input type="text" name="url" id="url" class="required url" />
            </td>
        </tr>
        <tr>
            <td>
                密码:
            </td>
            <td>
                <input type="password" name="password" id="password" />
            </td>
        </tr>
        <tr>
            <td>
                确认密码:
            </td>
            <td>
                <input type="password" name="confirm_password" id="confirm_password" />
            </td>
        </tr>
        <tr>
            <td>
                记住密码
            </td>
            <td>
                <input type="checkbox" name="checkbox11" id="checkbox" class="required" />
            </td>
        </tr>
        <tr>
            <td>
                <label for="passportId">
                    身份证号</label>
                <em>*</em>
            </td>
            <td>
                <input type="text" name="passportId" id="passportId" class="required" />
            </td>
        </tr>
        <tr>
            <td colspan="2" align="center">
                <br />
                <input type="submit" id="btn1" value="提交" />
            </td>
        </tr>
    </table>
    </form>
</body>
</html>

View中使用是Jquery Validation,同样是增加rule,用于客户端验证。具体可参考官方文档(后续有时间会放出中文版文档),以及之前这篇文章
JQuery+Asp.net MVC实现用户名重名查询


小结:在WEB页面中,是一个数据进入的接口,对数据合法性,正确性非常重要。做好表单数据验证工作可以防止那些攻击数据,以及不合理数据。
通过使用客户端和服务端双重验证,可以保证表单数据安全性。有的时候客户端验证并不是太安全的,可以设法绕开验证提交表单。所以服务端验证
也是需要的。但为了减轻服务器压力,尽量使用客户端验证。以上只是一个小小例子,欢迎讨论。希望本文对您有帮助。
 
作者:Petter Liu  http://wintersun.cnblogs.com  

posted on 2009-02-15 16:55  PetterLiu  阅读(17266)  评论(4编辑  收藏  举报