Model Validation(模型验证)

前言

阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html

本文参考链接文章地址http://www.asp.net/web-api/overview/formats-and-model-binding/model-validation-in-aspnet-web-api

当客户端发送数据给你的Web API时,你通常希望在做其它处理之前先对数据进行验证。

Data Annotations——数据注解

在ASP.NET Web API中,你可以使用System.ComponentModel.DataAnnotations命名空间的注解属性来设置模型属性的验证规则。考虑以下模型:

public class Product
{
public int Id { get; set; } [Required]
public string Name { get; set; }
public decimal Price { get; set; } [Range(0,999)]
public double Weight { get; set; }
}

如果你曾在ASP.NET MVC中使用过模型验证,这看上去是类似的。Required注解属性说明Name属性必须不为空。Range注解属性说明Weight必须在0-999之间。

假设客户端发送了一个带有下列JSON表示的POST请求:

{ "Id":4, "Price":2.99, "Weight":5 }

你可以看出,客户端并未包含被标记成required的Name属性。当Web API将该JSON转换成Product实例时,它会根据这些验证注解属性对Product进行验证。在控制器动作中,你可以检查该模型是否有效:

public class ProductsController : ApiController
{
public HttpResponseMessage Post(Product product)
{
if (ModelState.IsValid)
{
// Do something with the product (not shown).
// 用product做一些事(未表示出来) return new HttpResponseMessage(HttpStatusCode.OK);
}
else
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}
}

模型验证并不保证客户端数据是安全的。在应用程序的其它层面可能会需要附加验证(例如,数据层可能会强制外键约束)。

{"Id":4, "Name":"Gizmo"}

此处,客户端并未指定Price或Weight的值。JSON格式化器会将默认值(这里是零)赋给这些缺失的属性。

Under-Posting(递交不足)”:当客户端遗漏了某些属性时,便会发生“Under-posting”。例如,假设客户端发送如下:

此时模型的状态是有效的,因为零是这些属性的有效值。这是否是一个问题取决于你所处的场景。例如,在一个更新操作中,你可能希望区分出“零”与“未设置”。为了强迫客户端要设置一个值,将该属性构造成nullable(可空的),并设置Required注解属性:

[Required]
public decimal? Price { get; set; }

Over-Posting(过份递交)”:客户端也可能发送比期望还多的数据。例如:

{"Id":4, "Name":"Gizmo", "Color":"Blue"}

此处,JSON包含了Product模型中存在的属性(“Color”)。在这种情况下,JSON格式化器会简单地忽略该值(XML格式化器却不同)。若你的模型具有只读属性,Over-posting会产生问题。例如:

public class UserProfile
{
public string Name { get; set; }
public Uri Blog { get; set; }
public bool IsAdmin { get; set; } // uh-oh!(啊哦!)
}

如果你不想让用户对IsAdmin属性进行更新,并将其提升给管理员。最安全的策略是使用一个与允许客户端发送严格匹配的模型类:

public class UserProfileDTO
{
public string Name { get; set; }
public Uri Blog { get; set; }
// Leave out "IsAdmin"
// 略去了"IsAdmin"
}

Handling Validation Errors——处理验证错误

当验证失败时,Web API并不会自动地将错误返回给客户端。这取决于控制器动作对模型状态及响应进行适当的检查。

你也可以创建一个动作过滤器,以便在控制器动作被调用之前,检查模型的状态。以下代码演示了一个例子:

using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Http.ModelBinding; public class ModelValidationFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
if (actionContext.ModelState.IsValid == false)
{
// Return the validation errors in the response body.
// 在响应体中返回验证错误
var errors = new Dictionary<string, IEnumerable<string>>();
foreach (KeyValuePair<string, ModelState> keyValue in actionContext.ModelState)
{
errors[keyValue.Key] = keyValue.Value.Errors.Select(e => e.ErrorMessage);
} actionContext.Response =
actionContext.Request.CreateResponse(HttpStatusCode.BadRequest, errors);
}
}
}

如果模型验证失败,此过滤器会返回一个含有验证错误的HTTP响应。在此情况下,不会调用控制器动作。

HTTP/1.1 400 Bad Request
Server: ASP.NET Development Server/10.0.0.0
Date: Fri, 20 Jul 2012 21:42:18 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 239
Connection: Close {
"product": [
"Required property 'Name' not found in JSON. Line 1, position 18."
], "product.Name": [
"The Name field is required."
], "product.Weight": [
"The field Weight must be between 0 and 999."
]
}

如果你正在使用CodePlex上最新版的Web API,可以使用HttpError类将验证错误返回给客户端。HttpError类在RC版(指Web API的预览版)中无效。

你可以将此过滤器全局性地运用于所有Web API控制器。在Application_Start方法中,将此过滤器添加到HttpConfiguration.Filters集合:

protected void Application_Start()
{
// ... GlobalConfiguration.Configuration.Filters.Add(new ModelValidationFilterAttribute());
}

另一种可选办法是,通过将此过滤器作为注解属性进行添加,你可以将它运用于个别控制器或控制器动作:

public class ProductsController : ApiController
{
[ModelValidationFilter]
public HttpResponseMessage Post(Product product)
{
// ...
}
}
 

上周热点回顾(12.16-12.22)

 

热点随笔:

· 暴力英语学习法 + 严格的目标管理 = 成功快速靠谱的学好英语Jesse Liu
· .NET平台技术体系梳理+初学者学习路径推荐+我们的愿景与目标际为软件事务所
· “不给力啊,老湿!”:RSA加密与破解Vamei
· 开发人员解决不熟悉领域技术难题总结AllEmpty
· 当你手头没有工作的时候你在做什么?饮鸩止渴
· 我是这么利用数据——对需求说不欢乐的财神
· 使用DotNetBar制作漂亮的WinFrom界面,自定义AgileEAS.NET SOA平台WinClient主界面魏琼东
· 跨浏览器开发工作小结Gof Lee
· 我是这么利用数据——小身材,大味道欢乐的财神
· 一个小程序引发的思考幕三少
· 【探讨】javascript事件机制底层实现原理叶小钗
· 谈谈小菜眼中的博客园(想法和建议)田园里的蟋蟀

热点新闻:

· 趣文:如果老婆和女朋友她们是程序
· 周鸿祎:把自己当成打工的,一辈子都是打工的
· 关于程序员的59条搞笑但却真实无比的编程语录
· 国外一机器人否认自己是机器人
· 编程不只是技术,高考应有计算机一席之地
· 窃听CPU的声音就可破译最复杂的密码
· 杭州27岁淘宝三皇冠女卖家涉嫌两项罪名被批捕
· 一个创业者眼中的2014(上):学会寄生,忘掉平台
· 雷军:两场对谈,夸我骂我都是为我好
· 雾霾笼罩下的中国各地:太空俯瞰清晰可见
· G1诞生内幕
· 66岁“技术宅”发明简易输入法

知识库热点文章:

· 揭示记忆力的真相
· 多研究些问题,少谈些主义
· 领域建模中的七种坏味道信息
· 云风:一个编程的自由人
· 思考、学习新技术的原则和方式

 
 

Model Validation(模型验证)的更多相关文章

  1. Asp.Net Web API 2第十五课——Model Validation(模型验证)

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文参考链接文章地址htt ...

  2. webapi Model Validation 模型验证

    通常情况下,对于那些经常为别人提供数据接口的开发人员来说,对于调用方传递过来的参数都会有验证处理.例如: if (string.IsNullOrEmpty(entity.Name)) { //当姓名为 ...

  3. JSR 303 - Bean Validation 模型验证

    类是转载的,不知道转的哪里的. 此类依赖 JSR 303 – Bean Validation, Hibernate Validator. 代码不能直接运行.意会一下.自己改改. import com. ...

  4. Web API中的模型验证Model Validation

    数据注释 在ASP.NET Web API中,您可以使用System.ComponentModel.DataAnnotations命名空间中的属性为模型上的属性设置验证规则. using System ...

  5. <转>ASP.NET学习笔记之MVC 3 数据验证 Model Validation 详解

    MVC 3 数据验证 Model Validation 详解  再附加一些比较好的验证详解:(以下均为引用) 1.asp.net mvc3 的数据验证(一) - zhangkai2237 - 博客园 ...

  6. ASP.NET Core 中文文档 第四章 MVC(2.2)模型验证

    原文:Model Validation 作者:Rachel Appel 翻译:娄宇(Lyrics) 校对:孟帅洋(书缘) 在这篇文章中: 章节: 介绍模型验证 验证 Attribute 模型状态 处理 ...

  7. MVC遇上bootstrap后的ajax表单模型验证

    MVC遇上bootstrap后的ajax表单验证 使用bootstrap后他由他自带的样式has-error,想要使用它就会比较麻烦,往常使用jqueyr.validate的话只有使用他自己的样式了, ...

  8. Model Validation in ASP.NET Web API

    Model Validation in ASP.NET Web API 原文:http://www.asp.net/web-api/overview/formats-and-model-binding ...

  9. EMF学习,为了实现可扩展可自定义的模型验证 - 各种实现方法学习

    自: http://blog.csdn.net/javaman_chen/article/details/6057033 http://www.ibm.com/developerworks/cn/op ...

随机推荐

  1. JavaScript之数组去重

    前言:昨天看到了别人发的帖子,谈到了面试题中经常出现的数组去重的问题.作为一个热爱学习.喜欢听老师话的好孩纸,耳边忽然想起来高中老师的谆谆教导:不要拿到题就先看答案,要先自己思考解答,然后再对照答案检 ...

  2. sql小总结2

    SQL NULL 值 如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录.这意味着该字段将以 NULL 值保存. NULL 值的处理方式与其他值不同. NULL ...

  3. 我的MYSQL学习心得(五)

    原文:我的MYSQL学习心得(五) 我的MYSQL学习心得(五) 我的MYSQL学习心得(一) 我的MYSQL学习心得(二) 我的MYSQL学习心得(三) 我的MYSQL学习心得(四) 我的MYSQL ...

  4. [Mac] Mac book pro互换SSD硬盘、生产启动U菜、TimeMachine恢复 小记

    Mac book pro 硬盘故障.互换SSD硬盘.启动U磁盘生产 小记 2012新年买Mbp了.尽管各种功能都能用,但常常频繁的出现鼠标风火轮,已经下好的电影在本地播放时都会隔个几分钟卡一下. 拿到 ...

  5. 初识Java——(Java学习笔记一)

    冯诺依曼体系结构   JAVA核心优势:跨平台---通过JVM(java虚拟机)来实现   JVM:Java虚拟机的一种规范     标示符:只能以下划线.美元符号($).字母.数字组成,不能以数字开 ...

  6. MySQL Scale Out

    原文:MySQL Scale Out 简介 MySQL复制中较常见的复制架构有“一主一从”.“一主多从”.“双主”.“多级复制”和“多主环形机构”等,见下图: 最常用,也最灵活的就要数“一主多从”复制 ...

  7. 【翻译】C#和.NET核心快速参考

    原文:[翻译]C#和.NET核心快速参考 PS:在网上看到的一篇C#总结,英文的,总结的还可以,都是基础知识,翻译给大家学习.文章结尾有英文原版.发布地址:http://www.cnblogs.com ...

  8. [kmp+dp] hdu 4628 Pieces

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4622 Reincarnation Time Limit: 6000/3000 MS (Java/Ot ...

  9. C---通过指针访问数组

    C语言规定:如果指针变量P已指向数组中的一个元素,则P+1指向同一数组中的下一个元素. 引入指针变量后,就可以用俩种方法来访问数组元素了. 如果p的初值为&a[0],则: P+i 和a+i 就 ...

  10. 项目管理实践 -- 健身小管家(Fitness housekeeper)的管理(4)

    提前几天把检查更新的功能完成了.