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

Laughing
2017-12-08 / 2 评论 / 1,504 阅读 / 搜一下 / 正在检测是否收录...

在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;  
        }  
    }  
}

返回true或false代表验证是否通过。

客户端验证

自定义客户端验证就比较繁琐了,我们需要实现IClientValidatable接口的,

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;  
        }  
    }  
}
  1. 添加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;  
});
  1. 页面引入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

    看看哎

    回复