应无所住,而生其心
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术

ASP.NET MVC 模型验证

7613人阅读 2019/10/4 16:51 总访问:4712808 评论:0 收藏:1 手机
分类: .NET MVC


MVC自带有模型验证,它是通过System.ComponentModel.DataAnnotations命名空间完成。 我们要做的只是给Model类的各属性加上对应的验证特性(Attributes)就可以让MVC框架帮我们完成验证。


我们常规的验证就是喜欢写很多判断

如下:

[HttpPost]
public ActionResult Index(Register reg)
{
    if (String.IsNullOrEmpty(reg.UserName))
    {
        ModelState.AddModelError("UserName", "用户名不能为空");
    }
    else if (reg.UserName.Length < 6)
    {
        ModelState.AddModelError("UserName", "用户名长度不能小于6位");
    }
    if (ModelState.IsValidField("BirthDate") && reg.BirthDate > DateTime.Now)
    {
        ModelState.AddModelError("BirthDate", "生日不能为将来的时间");
    }
    if (ModelState.IsValid)
    {
        //保存数据
    }
    return View();
}

上面这种方式的验证虽然简单,很多人都能够立马上手,但是看到方法中N多个if语句的确不是个滋味,这种重复性的代码完全可以封装好然后通用。


使用特性进行验证:

[Required]:必填

[StringLength(60)]:字符串长度验证,最大60

[StringLength(50, MinimumLength = 6)]:字符串长度验证,最小6最大50

[Range(typeof(Decimal), "0", "100", ErrorMessage = "{0} 必须是数字介于 {1} 和 {2}之间.")]:范围跟上错误提示

[Range(typeof(decimal), "0.00", "49.99")]:小数的范围
[Range(typeof(DateTime), "11/10/2017", "11/10/2021")]:日期范围
[Range(35,44)]:范围

[RegularExpression(@”[A-Za-z0-9._%+-]+")]:正则的验证

[Compare("Password",ErrorMessage="密码要一致")]:进行两个值比较,比如用于密码是否相同

[Remote("CheckUserName", "Register", ErrorMessage = "用户名已被注册")]:远程验证


要验证很简单只需要使用ModelState.IsValid即可,就可以验证控制器接收到的模型

public ActionResult Do(TNBlogResource tnblogResource)
{
    //进行模型验证
    if (ModelState.IsValid)
    {
    }
    return View();
}

有些时候我们想要验证的不是写到方法参数上面的模型,是我们想要验证指定的模型实例

其实也很简单使用TryValidateModel即可

var movie = new Movie
{
    Title = title,
    Genre = genre,
    ReleaseDate = modifiedReleaseDate,
    Description = description,
    Price = price,
    Preorder = preorder,
};
//验证指定的模型实例
TryValidateModel(movie);

if (ModelState.IsValid)
{
    _context.AddMovie(movie);
    _context.SaveChanges();

    return RedirectToAction(actionName: nameof(Index));
}

return View(movie);

你使用了TryValidateModel后如果验证不通过想要看到具体的错误信息可以在调用一下ModelState.IsValid这样在ModelState中就可以看到具体的错误信息了

keys里边放的是出现错误的属性,如下

values里边就是具体的错误信息了


前台验证:

当然mvc里边的模型验证还可以配合前台验证,使用起来也比较简单

1:引入需要的js

前台验证使用的是jquery.validate,所以需要把相关的js引入进来一共需要三个

jquery,jquery.validate,jquery.validate.unobtrusive

<script src="~/Scripts/jquery-3.3.1.js"></script>
<script src="http://static.runoob.com/assets/jquery-validation-1.14.0/dist/jquery.validate.min.js"></script>
<script src="~/content/jquery.validate.unobtrusive.min.js"></script>

其实呢前台只用jquery.validate.js就行,只是jquery.validate.unobtrusive是封装好的更好的配合asp.net mvc中的模型验证使用,可以更方便快捷的输出错误信息。

可以在运行时由服务器端根据Model中设置的验证规则,自动生成客户端验证js代码(结合jquery.validate)。这很好地解决了表单验证时一次代码,两次验证(客户端+服务器端)的问题

jquery.validate.unobtrusive.js下载地址:

https://download.tnblog.net/resource/index/03b887338c5a4c92a8562ad4c8dbab53

注意js的引入顺序,这个js要在前面两个js之后引入


如果只是纯前端的验证,也就是jquery.validate的使用,可以参考:

https://www.tnblog.net/aojiancc/article/details/2643



2:输入框的生成使用TextBoxFor的方式

//申明model
@model EFLearn2.Users
//根据Model生成文本框
@Html.TextBoxFor(a => a.UserName)
@Html.TextBoxFor(a => a.Number)
@Html.TextBoxFor(a => a.UClass)

因为这种方式生成,他会把相关的错误配置,根据后台那个模型配置都生成好,这样就可以很好把后台的模型配置和前台结合起来了

根据生成的input标签的结果,我们可以很好的知道,前台的jquery验证插件的错误配置根据后台模型配置自动生成好了,非常方便,不需要从新在写一次



3:在想要输出错误信息的地方使用@Html.ValidationSummary()

其实它就是帮我们生成了一串html代码用于显示错误信息:

<div class="validation-summary-valid" data-valmsg-summary="true">
   <ul>
       <li style="display:none"></li>
  </ul>
</div>

当然这串代码你完全可以自己写,只是我们用这个html帮助类会更快捷一点


4:然后使用验证插件的valid方法,即可知道有没有通过验证,没有通过验证就会输出错误信息

var exeupdate = function (param) {
    //是否验证通过
    if ($("#updateform").valid()) {
      //验证通过后的逻辑
    }
}

效果如下:

显示红色我们给一个样式即可:

.validation-summary-errors {
    color: red;
}

前台的所有代码如下:

<link href="~/media/css/bootstrap.min.css" rel="stylesheet" />
<link href="~/media/css/style.css" rel="stylesheet" />
<script src="~/media/js/jquery-1.10.1.min.js"></script>
<script src="http://static.runoob.com/assets/jquery-validation-1.14.0/dist/jquery.validate.min.js"></script>
<script src="~/content/jquery.validate.unobtrusive.min.js"></script>
<script src="~/content/myjquery.js"></script>
<style>
    .validation-summary-errors {
        color: red;
    }

    .field-validation-error {
        color: red;
    }
</style>
@model EFLearn.Users
<div style="width: 88%; margin: 60px auto" id="updatediv">
    <form id="updateform">
        <div class="row-fluid">
            <div class="span6">
                <h4>用户</h4>
                <input type="hidden" id="Id" name="Id" />
                <p>
                    @Html.TextBoxFor(a => a.UserName, new { @class = "span12 m-wrap" })
                </p>
                <h4>学号</h4>
                <p>
                    @Html.TextBoxFor(a => a.Number, new { @class = "span12 m-wrap" })
                </p>
            </div>
            <div class="span6">
                <h4>班级</h4>
                <p>
                    @Html.TextBoxFor(a => a.UClass, new { @class = "span12 m-wrap" })
                </p>
                <h4>状态</h4>
                <p>
                    <select class="span12 m-wrap" id="CheckType" name="CheckType">
                        <option value="1">审核通过</option>
                        <option value="2">正在审核</option>
                        <option value="3">审核失败</option>
                    </select>
                </p>
            </div>
        </div>
        @Html.ValidationSummary()
    </form>
</div>

<script>
    var inject = function (obj) {
        $("#updateform").injectValue(obj);
    }
    var exeupdate = function (param) {
        //是否验证通过
        if ($("#updateform").valid()) {
          //验证通过后的逻辑
        }
    }
</script>

tip:网上有人说验证要生效前台的表单必须要使用@html.form来生成才可以,我这里没有使用也是可以的。只是像@Html.ValidationSummary()这类输出验证的要放到form标签里边才行,这点要注意。


把验证的错误信息放到指定的地方

上面是通过@Html.ValidationSummary()把所有错误信息输入到一个地方

当然也可以使用@Html.ValidationMessageFor来指定具体某个字段的错误信息和输出位置

<div class="span6">
    <h4>用户</h4>
    <input type="hidden" id="Id" name="Id" />
    <p>
        @Html.TextBoxFor(a => a.UserName, new { @class = "span12 m-wrap" })
        @Html.ValidationMessageFor(a => a.UserName)
    </p>
    <h4>学号</h4>
    <p>
        @Html.TextBoxFor(a => a.Number, new { @class = "span12 m-wrap" })
        @Html.ValidationMessageFor(a => a.Number)
    </p>
</div>

如下:用户和学号的错误信息都被显示到输入框的下面了

当然我这个错误信息这样显示样式就会错乱了,只是为了说明一下@Html.ValidationMessageFor可以把错误信息输入到想要的地方去


前台验证是否全部为空格

添加一个方法:

// 全空格验证
$.validator.addMethod("isBlank", function (value, element) {
    var blank = /^[ ]*$/;
    return this.optional(element) || !(blank.test(value));
}, "不能全输入空格");

使用的时候在class里边添加上isBlank就好了

  <input id="love" name="love" class="isBlank" required />


tip:代码标准和规范也是非常重要的,不会让整个项目越写越乱


参考项目下载地址:https://download.tnblog.net/resource/index/54f28c67148d4ac4b95dbf3d2ea5da9a



当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!




欢迎加群讨论技术,群:677373950(满了,可以加,但通过不了),2群:656732739

评价