博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Asp.Net Web API 2第十五课——Model Validation(模型验证)
阅读量:4586 次
发布时间:2019-06-09

本文共 4152 字,大约阅读时间需要 13 分钟。

原文:

前言

阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 

本文参考链接文章地址

当客户端发送数据给你的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
>(); foreach (KeyValuePair
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 RequestServer: ASP.NET Development Server/10.0.0.0Date: Fri, 20 Jul 2012 21:42:18 GMTContent-Type: application/json; charset=utf-8Content-Length: 239Connection: 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类在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)    {        // ...    }}
posted on
2014-03-18 23:35 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/3609136.html

你可能感兴趣的文章
[bzoj] 1597 土地购买 || 斜率优化dp
查看>>
Lodop的JS模版代码、文档式模版 生成加载赋值博文索引
查看>>
Python安装和开发环境搭建
查看>>
[USACO4.2] 草地排水 Drainage Ditches (最大流)
查看>>
dotnetcore+vue+elementUI 前后端分离 三(前端篇)
查看>>
gdb输入输出重定向
查看>>
包含.h就可以用其对应的函数
查看>>
【转】block一点也不神秘————如何利用block进行回调
查看>>
mysql忘记root密码的处理方法
查看>>
Newtonsoft.Json之JArray, JObject, JProperty,JValue
查看>>
OO Summary (Homework 9-11)
查看>>
fedora 解决yumBackend.py进程CPU占用过高
查看>>
NTP 协议介绍
查看>>
软件测试 · 白盒测试
查看>>
docker-compose exec时出现"fork/exec /proc/self/exe: no such file or directory" 报错
查看>>
IIS的安装及网站发布的图解
查看>>
VM虚拟机安装苹果雪豹操作系统
查看>>
dos进去mysql导入数据库
查看>>
Oracle单表去重复(一)
查看>>
C#中如何获取一个二维数组的两维长度,即行数和列数?以及多维数组各个维度的长度?...
查看>>