ASP.NET MVC客户端及服务端验证

Laughing
2017-12-08 / 2 评论 / 1,468 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年03月21日,已超过303天没有更新,若内容或图片失效,请留言反馈。

在mvc中使用表单进行数据提交时,数据验证分为服务器端验证和客户端验证;
我们可以通过使用HtmlHelper中的方法及在页面中引用js库对Model的属性的数据注解(System.ComponentModel.DataAnnotations命名空间下的一组类)进行解析,实现前端、后端的数据验证;
其实客户端验证也是调用的jquery.validate.js,我个人觉得,通过数据注解,服务端的验证确实能够方便不少,但是客户端的验证,感觉还不如直接用jquery.validate来的方便。
数据注解以及微软内置的验证这里就不多介绍了,这里我们主要介绍一下如何实现服务端和客户端自定义验证

前期准备代码,实体类、控制器、视图

实体类

using me.lisen.MVC.Public;  
using System;  
using System.Collections.Generic;  
using System.ComponentModel.DataAnnotations;  
using System.Linq;  
using System.Web;  
  
namespace me.lisen.MVC.Models  
{  
    public class Product  
    {  
        [Key]  
        public string ID { get; set; }  
  
        [Display(Name="产品名称")]  
        [Required(ErrorMessage ="请输入产品名称")]  
        [StringLength(2,ErrorMessage ="最多输入两个字符")]  
        public string Name { get; set; }  
  
        [Display(Name ="价格")]  
        [Required(ErrorMessage ="请输入价格")]  
        [PriceValid(MinPrice =20.00,ErrorMessage ="价格不能低于20元")]  
        public Decimal Price { get; set; }  
    }  
}

控制器

using me.lisen.MVC.Models;  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.Web.Mvc;  
  
namespace me.lisen.MVC.Controllers  
{  
    public class ProductController : Controller  
    {  
        // GET: Product  
        public ActionResult Create()  
        {  
            return View();  
        }  
  
        [HttpPost]  
        public ActionResult Create(Product product)  
        {  
            if (ModelState.IsValid)  
            {  
                return RedirectToAction("Create");  
            }  
            return View();  
        }  
    }  
}

视图

@model me.lisen.MVC.Models.Product  
  
@{  
    ViewBag.Title = "Create";  
}  
  
<h2>Create</h2>  
  
@using (Html.BeginForm())   
{  
    @Html.AntiForgeryToken()  
      
    <div class="form-horizontal">  
        <h4>Product</h4>  
        <hr />  
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })  
        <div class="form-group">  
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })  
            <div class="col-md-10">  
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })  
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })  
            </div>  
        </div>  
  
        <div class="form-group">  
            @Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })  
            <div class="col-md-10">  
                @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })  
                @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })  
            </div>  
        </div>  
  
        <div class="form-group">  
            <div class="col-md-offset-2 col-md-10">  
                <input type="submit" value="Create" class="btn btn-default" />  
            </div>  
        </div>  
    </div>  
}  
  
<div>  
    @Html.ActionLink("Back to List", "Index")  
</div>

服务端验证

实现自定义的服务端验证非常简单,我们只需要继承ValidationAttribute类,然后重写IsValid()方法即可

using System;  
using System.Collections.Generic;  
using System.ComponentModel.DataAnnotations;  
using System.Linq;  
using System.Web;  
using System.Web.Mvc;  
  
namespace me.lisen.MVC.Public  
{  
    public class PriceValid:ValidationAttribute  
    {  
        public double MinPrice { get; set; }  
  
              public override bool IsValid(object value)  
        {  
            if (value == null)  
            {  
                return true;  
            }  
            var price = Convert.ToDouble(value);  
            if(price < MinPrice)  
            {  
                return false;  
            }  
            return true;  
        }  
    }  
}
`1``
返回true或false代表验证是否通过。
## 客户端验证
自定义客户端验证就比较繁琐了,我们需要实现`IClientValidatable`接口的, 
​```java
public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context
)

方法,然后在方法中定义传递给js的方法名以及方法参数。

  1. 实现接口IClientValidatable

    using System;  
    using System.Collections.Generic;  
    using System.ComponentModel.DataAnnotations;  
    using System.Linq;  
    using System.Web;  
    using System.Web.Mvc;  
      
    namespace me.lisen.MVC.Public  
    {  
     public class PriceValid:ValidationAttribute,IClientValidatable  
     {  
         public double MinPrice { get; set; }  
      
         public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)  
         {  
             var rule = new ModelClientValidationRule();  
             rule.ErrorMessage = metadata.GetDisplayName() + "不能小于系统限制";  
             rule.ValidationParameters.Add("minprice", MinPrice);  
             rule.ValidationType = "price";  
             yield return rule;  
         }  
      
         public override bool IsValid(object value)  
         {  
             if (value == null)  
             {  
                 return true;  
             }  
             var price = Convert.ToDouble(value);  
             if(price < MinPrice)  
             {  
                 return false;  
             }  
             return true;  
         }  
     }  
    }
  2. 添加js文件

    /* 
    第一个参数是服务端ValidationType值 
    第二个参数必须是ValidationParameters.Add()的值 
    */  
      
    $.validator.unobtrusive.adapters.addSingleVal("price", "minprice");  
      
    $.validator.addMethod("price", function (value, element, param) {  
     if (value) {  
         var inputValue = parseInt(value, 10);  
         var validateValue = parseInt(param, 10);  
         if (inputValue < validateValue) {  
             return false;  
         }  
     }  
     return true;  
    });
  3. 页面引入js文件
2

评论 (2)

取消
  1. 头像
    中医秘方
    Windows 7 · Google Chrome

    一言不发岂能证明我来过了?!

    回复
  2. 头像
    云缠月
    Windows 7 · Google Chrome

    这样精彩的博客越来越少咯!

    回复
  3. 头像
    vivi
    iPhone · Google Chrome
    @ Laughing

    我移过去之后,iCloud再打开清空了云盘里的所有内容……什么都没了

    回复
  4. 头像
    stayma
    Windows 10 · Google Chrome

    看看哎

    回复