Asp.Net MVC 模型验证详解-实现客户端、服务端双重验证

时间:2022-12-30 13:08:08

概要

在asp.net webform开发中经常会对用户提交输入的信息进行校验,一般为了安全起见大家都会在客户端进行Javascript(利于交互)、服务端双重校验(安全)。书写校验代码是一个繁琐的过程。在Asp.Net MVC中就很好的解决了这一问题、利用模型的数据注解实现客户端与服务端双重校验,使你的开发效率大大提高。

数据注解

微软提供了很多数据注解的类(通俗点就是特性标签类),也为我们提供了自定义接口来满足开发人员不同的需求。下面一一为大家说明。

命名空间:System.ComponentModel.DataAnnotations;

    程序集:System.ComponentModel.DataAnnotations;

StringLength特性-限制长度

这个特性看它命名规则就知道它是什么意思了,字符串长度对吧。是的你没看错,就是字符串长度。实例代码:

[StringLength(,ErrorMessage = "密码不能超过20个字符")]
public string Password { get; set; }

我们只需要在模型属性上加上这么个特性,那么校验的时候这个字符串不能超过20个字符。ErrorMessage就是校验不通过时的消息。

Required特性-不能为空

这个特性表必须的、不能为空的。用于不为空校验。默认为不允许为空。允许为空则添加AllowEmptyStrings = true

[Required(ErrorMessage = "密码不能超过20个字符")]
public string Password { get; set; }

RegularExpression-规则校验(正则校验)

正则表达式在校验中是必不可少的一部分、微软也为我们提供了这个类型,非常方便的使用。

[RegularExpression(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "邮箱不正确")]
public string Email { get; set; }

Range-数值范围

当对一个数值进行校验时、一般可能会用到取值范围。比如年龄:

[Range(,,ErrorMessage = "年龄取值范围0-120")]
public int Age { set; get; }

Compare-比较

比较两个值是否一致,一般用于二次输入。Password是需要比较的值

[Compare("Password",ErrorMessage = "两次输入不一致")]
public string PasswordConfirm { get; set; }

Remote-远程校验

这个在登录的时候用的非常多。比如你的用户名ID是否已经被注册,这是需要从数据库查询之后才知道的。这个类有些特殊,它不在System.ComponentModel.DataAnnotations命名空间下,它是在System.Web.Mvc;命名空间下的。

[Remote("CheckUserName","Register",ErrorMessage = "用户名已被注册")]
public string UserName { get; set; }

Action:代表你要请求的方法

Controller:表示你要请求的控制器

这个特性有一个约定,就是你请求的这个路径必须返回True或False,并且是以Json格式返回的。至于返回True或False的逻辑,看大家自己的需求了。

public ActionResult CheckUserName()
{
return Json(false, JsonRequestBehavior.AllowGet);
}

Display-显示名称

这个特性、个人认为不属于校验里面的一部分,它只是用户前台展示时的一个显示名称。后面在为大家讲解这个的实际应用

[Display(Name = "年龄")]
public int Age { set; get; }

总结:

通过以上五种模型注解,一般能满足生产中大部分校验,如有特殊校验,可以自定义特性来进行模型注解。了解了模型注解,也就是开始我们asp.net MVC校验的第一步了。自定义数据注解我就不说了,看下这个就可以了:

http://www.cnblogs.com/zhangkai2237/archive/2012/12/12/2814825.html

数据绑定及验证

首先要进行客户端校验有几个比较重要的点:

1、  必须要用@Html.BeginForm()这种方式包含住输入标签。(自己试验了下,是这样的。如果有错误请好心提醒)

2、  必须要用强类型页面。

3、  必须要引用Jquery库、Jquery.Validate、Jquery.Validate.unobtrusive这三个文件

4、  web.config文件中这两个值必须为True。默认为True

<appSettings>
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

前台代码:

由于我时间问题、我创建视图的时候就直接创建了编辑视图了。

   <script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> @using (Html.BeginForm("Create","Register")) {
@Html.ValidationSummary(true)
<fieldset>
<legend>RegisterViewModel</legend> <div class="editor-label">
@Html.LabelFor(model => model.UserName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.UserName)
@Html.ValidationMessageFor(model => model.UserName)
</div> <div class="editor-label">
@Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Password)
@Html.ValidationMessageFor(model => model.Password)
</div> <div class="editor-label">
@Html.LabelFor(model => model.PasswordConfirm)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.PasswordConfirm)
@Html.ValidationMessageFor(model => model.PasswordConfirm)
</div> <div class="editor-label">
@Html.LabelFor(model => model.Phone)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Phone)
@Html.ValidationMessageFor(model => model.Phone)
</div> <div class="editor-label">
@Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Email)
@Html.ValidationMessageFor(model => model.Email)
</div> <p>
<input type="submit" value="Save" />
</p>
</fieldset>
}

补充前面一个内容、在属性前加上Display特性,那么在前台@Html.LabelFor(model => model.Email)这种代码就会优先使用Display里面定义的名称,如果没有定义,则显示属性的名称(UserName)。

后台代码:

public class RegisterController : Controller
{
//
// GET: /Register/ public ActionResult Index()
{
if (ModelState.IsValid)
{
//后台校验。判断所有数据是否建议通过、
}
return View();
} public ActionResult CheckUserName()
{
return Json(false, JsonRequestBehavior.AllowGet);
} [HttpPost]
public ActionResult Create(RegisterViewModel model)
{
return View();
}
}

使用Entity Framework模型

在实际生产中我们用到的很有可能就是ORM框架,或者代码生成器生成的代码。为了避免每次重新生成后而将我们的数据注解给消失掉、微软也提供了一种叫元数据共享的一种方式(我叫它”元数据”共享)

    /// <summary>
/// 验证类
/// </summary>
public class RegisterViewModel_Validate
{
[Display(Name = "用户名")]
[Required(ErrorMessage = "不能为空",AllowEmptyStrings = false)]
[Remote("CheckUserName","Register",ErrorMessage = "用户名已被注册")]
public string UserName { get; set; } [Display(Name = "密码")]
[Required(ErrorMessage = "密码不能超过20个字符")]
public string Password { get; set; } [Display(Name = "确认密码")]
[System.ComponentModel.DataAnnotations.Compare("Password",ErrorMessage = "两次输入不一致")]
public string PasswordConfirm { get; set; } [Display(Name = "公司电话")]
[Required(ErrorMessage = "公司电话不能为空")]
[StringLength(, ErrorMessage = "错误的公司电话")]
[RegularExpression("^[0-9]+$", ErrorMessage = "公司电话不正确")]
public string Phone { get; set; } [Required(ErrorMessage = "注册人邮箱不能为空")]
[RegularExpression(@"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "邮箱不正确")]
public string Email { get; set; } [Display(Name = "年龄")]
[Range(,,ErrorMessage = "年龄取值范围0-120")]
public int Age { set; get; }
}
/// <summary>
/// 自动生成的类
/// </summary>
[MetadataType(typeof(RegisterViewModel_Validate))]//该类共享RegisterViewModel_Validate元数据
public partial class RegisterViewModel
{ }

我来了看起来方便就将两个类放到了一个文件夹下面,在生产中你还是得分开他们,不然自动生产代码还是会覆盖我们写的验证代码。

总结:

  想想应该算是比较完整的了。希望对一些还不太明白的朋友有所帮助,自己也重新加深了印象。从事MVC开发后,

感觉开发起来确实比较Web Form Happy多了,asp.net MVC这种开发方式我非常喜欢,而且可操作性、灵活性更强。

希望更多的朋友一起加入MVC的阵营吧。一起享受MVC 编码的乐趣.....

  还有不明白的朋友可以私密我。欢迎讨论

Asp.Net MVC 模型验证详解-实现客户端、服务端双重验证的更多相关文章

  1. 【ASP&period;NET MVC系列】详解View

    本篇文章内容属于ASP.NET MVC系列视图篇,主要讲解View,大致内容如下: 1.Views文件夹讲解 2.View种类 3.Razor语法 4.对视图的基本操作 一   Views文件夹 (一 ...

  2. ASP&period;NET MVC和WebForm 轻松实现前端和后端的双重验证 jquery&period;validate&plus;ValidationSugar

    上次不足的改进 可能上一个贴子给大家带来很多误解,所以我这次把DEMO完善了两个版本 [ASP.NET WEBFROM]和[ ASP.NET MVC] 修改了一些BUG,并且修改了一些细了 在上个贴子 ...

  3. 在ASP&period;NET MVC下实现单个图片上传&comma; 客户端服务端双重限制图片大小和格式&comma; 服务端裁剪图片

    在"MVC文件图片ajax上传轻量级解决方案,使用客户端JSAjaxFileUploader插件01-单文件上传"一文中,使用JSAjaxFileUploader这款插件实现了单文 ...

  4. 资深P7架构师详解淘宝服务端高并发分布式架构演进之路

    1. 概述 本文以淘宝作为例子,介绍从一百个并发到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则. ...

  5. ASP&period;NET MVC路由配置详解

    命名参数规范+匿名对象 routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", ...

  6. 转:SVN 版本服务器搭配全过程详解(含服务端、客户端)

    1.为什么要用VisualSVN Server,而不用Subversion? 回答: 因为如果直接使用Subversion,那么在Windows 系统上,要想让它随系统启动,就要封装SVN Serve ...

  7. SVN 版本服务器搭配全过程详解(含服务端、客户端)

    1.为什么要用VisualSVN Server,而不用Subversion? 回答: 因为如果直接使用Subversion,那么在Windows 系统上,要想让它随系统启动,就要封装SVN Serve ...

  8. ASP&period;NET MVC学习之模型验证详解

    ASP.NET MVC学习之模型验证篇 2014-05-28 11:36 by y-z-f, 6722 阅读, 13 评论, 收藏, 编辑 一.学习前的一句话 在这里要先感谢那些能够点开我随笔的博友们 ...

  9. ASP&period;NET没有魔法——ASP&period;NET MVC 模型验证

    在前面的文章中介绍了用户的注册及登录功能,在注册用户时可以通过代码的形式限制用户名及密码的格式,如果不符合要求那么就无法完成操作,如下图: 该功能的原理是Identity基于的Entity Frame ...

随机推荐

  1. GitLab CI持续集成配置方案&lpar;补&rpar;

    上篇文章介绍了GitLab CI的持续集成配置方法,本篇文章将主要介绍NUnit的持续集成和遇到的一些坑 1.NUnit单元测试持续集成 下载NUnit.3.4.1.msi,https://githu ...

  2. hongxin

    邀请链接 :http://honx.in/_VbiG2CZDjwIE8l1t

  3. 《java编程思想》读书笔记(一)开篇&amp&semi;第五章&lpar;1&rpar;

    2017 ---新篇章  今天终于找到阅读<java编程思想>这本书方法了,表示打开了一个新世界. 第一章:对象导论 内容不多但也有20页,主要是对整本书的一个概括.因为已经有过完整JAV ...

  4. Oracle笔记 十一、PL&sol;SQL函数和触发器

    --创建函数 create or replace function add_sal(sSal number) return number is begin if (sSal > 5000) th ...

  5. Drawer Layout

    http://developer.android.com/training/implementing-navigation/nav-drawer.html#DrawerLayout <menu ...

  6. JS Message 网页消息提醒

    JS message是一个非常小的(用gzip压缩之后才3kb)JavaScript library 用于轻松在网页上展示通知提醒.除了通知,它还支持创建带风格的对话框和确认对话框.不需要任何JS框架 ...

  7. Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (二) —— SQLite

    SQLite是一种转为嵌入式设备设计的轻型数据库,其只有五种数据类型,分别是: NULL: 空值 INTEGER: 整数 REAL: 浮点数 TEXT: 字符串 BLOB: 大数据 在SQLite中, ...

  8. 阿里图标库iconfont入门使用

    目前大多数的互联网公司,前端开发和UI设计师配合中,针对设计师给图的效果图,前端开发工程师不再像往常一样对于细小图标进行切图,取而代之的是引用阿里图标库(http://iconfont.cn/):简单 ...

  9. 搭建iview环境

    一.最快捷方式安装: $ npm install iview --save 二.一般在 webpack 入口页面 main.js 中如下配置: import Vue from 'vue'; impor ...

  10. 如何快速学好Shell脚本?

    Shell 语言作为类 Unix 系统的原生脚本,有着非常实用的价值.但对于很多刚刚接触 Shell 脚本的同学来说,搞懂 Shell 语言的语法却是一件非常困难的事情.甚至有人吐槽,或许没有谁能清楚 ...