发文章
发文工具
撰写
网文摘手
文档
视频
思维导图
随笔
相册
原创同步助手
其他工具
图片转文字
文件清理
AI助手
留言交流
前言
阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html
本文参考链接文章地址http://www./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) { // ... } }
来自: 昵称10504424 > 《工作》
0条评论
发表
请遵守用户 评论公约
ASP.NET Web API现使用Json.NET,获得若干增强
ASP.NET Web API现使用Json.NET,获得若干增强。ASP.NET Web API发布候选版获得了若干增强,如将Json.NET作为默认的序列化器,可测试性更好的Http消息处理器,以及IAPIExplorer API等等。
ASP.NET 实现多站点统一登录
ASP.NET 实现多站点统一登录现在网络上的身份验证一般都是采用用户名+口令的形式,几乎每到一个提供服务的网站都要求进行验证登录。我们知道Http是无连接协议, 而Cookie可以标识特定站点的用户信息, A...
ASP.NET Web API(二):安全验证之使用HTTP基本认证
ASP.NET Web API(二):安全验证之使用HTTP基本认证。HTTP基本认证原理。在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允...
模組化的 IIS 7 與 .NET 能力整合
IIS(Internet Information Services)不僅是 Windows Server 的重要功能,Windows 用戶端作業系統也有這項功能,而 Windows Vista 以及...
ASP.NET MVC随想录(1):漫谈OWIN
OWIN在.NET Web Servers与Web Application之间定义了一套标准接口,OWIN的目标是用于解耦Web Server和Web Application。过去,IIS作为.N...
VS2005将支持的两种WEB编程模型的比较
VS2005将支持的两种WEB编程模型的比较 2006年4月17日 14:02上篇Blog我介绍了Visual Studio 2005 Web Application Projects 项目,下面来比较一下它跟 Visual Studio 2005 Web Site Projects 使用的场...
ASP.NET MVC的Web Api的实练
ASP.NET MVC的Web Api的实练。学习ASP.NET MVC一年多来,现在该学学Web Api了。API与ASP.NET MVC的Controller差不多。当你在专案中创建...
VS2008 Web Application和Web Site的区别[转] - 无名 - ...
VS2008 Web Application和Web Site的区别[转] - 无名 - ...编译(Build)命令仅仅是测试这个WEB站点是否编译正确,调试一个WEB站点项目的时候,是通过依赖你的源代码文件,ASP.net进行动态编译页面和类...
WCF-安全之身份验证与授权
WCF-安全之身份验证与授权。某些网关守卫(例如 ASP.NET 文件授权、企业服务 (COM+) 角色和 Windows ACL)要求经过身份验证的 Windows 标识,此类标识采用 WindowsIdentity 对象的形式,该对象封装的是...
微信扫码,在手机上查看选中内容