实战 ASP.NET Web API

Web API 框架是一个面向 Http 协议的通信框架。相对于 WCF 而言,Web API 只面向于 Http 协议设计,而且没有 WCF 那么繁琐的配置。Web API 的开发类似于 ASP.NET MVC 中控制器的开发,但是相对于直接使用 ASP.NET MVC 来返回 Json 对象的方式而言,Web API 封装了数据的序列化、反序列化,接口、实现都更加简单。 简单地说,如果要向浏览器、移动端提供 Json 数据格式的 API,则应该首选 Web API 作为通信框架。

以下,我列出了在当前使用 Web API 开发系统时,遇到的几个知识点或问题。

数据序列化

Web API 框架目前支持两种数据格式的序列化:Json 及 Xml。在不做任何配置的情况下,如果 Http 请求中,HttpHeader 中 Accept 被指定为 accept: application/xml,则 Web API 会自动把数据使用 xml 进行序列化,否则使用 json 序列化。 如果期望不使用 xml 序列化数据,我们可以通过 GlobalConfiguration.Configuration.Formatters 来进行配置:config.Formatters.Remove(config.Formatters.XmlFormatter)。

一般情况下,我们会使用 Json 序列化。跟 ASP.NET MVC 的 Json 序列化不同的是,Web API 使用了 Newtonsoft.Json 框架来进行序列化。(例如,JsonMediaTypeFormatter.SerializerSettings 属性就是 Newtonsoft.Json.JsonSerializerSettings 类型,可以直接对序列化进行配置。) Json 序列化支持对匿名类型进行进行序列化,这大大方便了开发人员,例如,我们可以随意组装数据并直接返回:

   1:  [HttpGet]
   2:  public IEnumerable AllGet()
   3:  {
   4:      return new string[] { "Item1", "Item2" }.Select(s => new
   5:      {
   6:          Name = s,
   7:          Code = s,
   8:          Items = new ArrayList
   9:          {
  10:              new { Name = "Item1" },
  11:              new { Name = "Item2" },
  12:              new { Name = "Item3" },
  13:              new { Name = "Item4" },
  14:          }
  15:      });
  16:  }

另外,Web API 提供了 HttpResponseMessage 类型可作为返回值,使得开发人员可以对 HttpResponse 做一些更详细的设置。而且,如果不期望修改返回值类型而直接返回 HttpResponse 时,可以使用 HttpResponseException 间接返回一个 HttpResponseMessage。

Action 匹配

Web API 框架默认是基于 Restful 架构模式的,与 ASP.NET MVC 有区别的是,它会根据 Http 请求的 HttpMethod(Get、Post、Put、Delete) 来在 Controller 中查找 Action,规则是:Action 名中是否以 Get、Post 开头?Action 上标记 HttpGet、HttpPost 等标记?并会完全忽视 Action 的方法名。

例如,Web API 对于资源的 CRUD 操作,采用如下格式: get /API/models/ 查询所有实体 get /API/models/1000 查询id为1000的实体 post /API/models/ {id:-1, name:'name'} 添加一个实体 put /API/models/ {id:1000, name:'name'} 更新指定实体 delete /API/models/1 删除指定实体

由于忽视了方法名,所以的几个方法,在调用时会抛出异常:

在面向服务的架构中,往往不会直接把底层的实体公布出来,让客户端直接进行 CRU 操作;而是公布一些粗粒度的 RPC 形式的服务操作。要使用 Web API 框架,我们需要修改默认的配置。例如,让客户端在调用时显式指定 action 名称:

   1:  config.Routes.MapHttpRoute(
   2:      name: "DefaultApi",
   3:      routeTemplate: "api/{controller}/{action}/{id}",
   4:      defaults: new { id = RouteParameter.Optional }
   5:  );

这样,由于显式指定了 Action 名称,Web API 会使用该名称来查找对应的 Action 方法,而不再按照 HttpMethod 约定来查找对应的 Action。例如,对于以下 API 的调用如下:

   1:  [HttpGet]
   2:  public HttpResponseMessage Login(string userName, string password)
   3:  {
   4:      return Request.CreateResponse(HttpStatusCode.NotFound);
   5:  }

调用方法: get /api/account/login/?username=hqf@qq.com&password=dsd

关于 POST 参数绑定

Web API 相对于 ASP.NET MVC,使用了新的参数绑定类。要注意的是,Action 参数列表中只能有一个参数可以从 Http Post Body 中反序列化出来。如果参数列表中只有一个参数,而且它的类型是一个复杂类型,那么 Web API 会直接把 Body 尝试反序列化为该类的对象。如果有多个参数,那么要从 Body 反序列化的那个参数,需要标记上 [FromBodyAttribute]。 相关内容,比较复杂,可以参考以下文章:  http://www.cnblogs.com/sicket/archive/2012/06/28/2567129.html http://www.cnblogs.com/lushuicongsheng/archive/2012/10/27/2742214.html http://www.tuicool.com/articles/eQzyEv http://weblogs.asp.net/cibrax/archive/2012/08/10/binding-form-data-in-asp-net-web-api.aspx

不错的示例代码

MSDN 上有一个比较全面的示例代码: http://code.msdn.microsoft.com/ASPNET-Web-API-JavaScript-d0d64dd7

本文讲得比较浅,只是列举一些开发过程中会经常遇到的需要注意的点。解决这些问题后,我们的系统,已经开始使用 Web API 来进行开发了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏比原链

剥开比原看代码11:比原是如何通过接口/create-account创建帐户的

Gitee地址:https://gitee.com/BytomBlockchain/bytom

12710
来自专栏惨绿少年

Redis 数据库

1.1 Redis简介 ? 1.1.1 介绍 Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对(key-value)存储数据库...

846130
来自专栏大内老A

.NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”

FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为...

22560
来自专栏大内老A

通过添加HTTP Header实现上下文数据在WCF的自动传递

多年之前,我写了一篇通过WCF扩展实现上下文信息从客户端自动传递到服务端的文章,其实现机制很简单:将上下文信息存放到SOAP Header进行传递。那么对于非S...

499100
来自专栏Golang语言社区

Golang语言社区--LollipopGO开源项目搭建商城路由分发

大家好,我是Golang社区主编彬哥,还是要继续社区的开源项目LollipopGO轻量级web框架实战商城。

726200
来自专栏技术博客

设计模式之四(抽象工厂模式第一回合)

首先关于抽象工厂模式的学习,我们需要慢慢的,由浅入深的进入。不能单刀直入,否则可能达不到预期学明白的目标。

11910
来自专栏菩提树下的杨过

Ado.Net连接池的速度测试

晚上闲来无事,突然想测试一下Ado.Net连接池带来的连接速度提升,写了以下代码: using System; using System.Configura...

22260
来自专栏码洞

欲求不满之 Redis Lua 脚本的执行原理

Redis 提供了非常丰富的指令集,但是用户依然不满足,希望可以自定义扩充若干指令来完成一些特定领域的问题。Redis 为这样的用户场景提供了 lua 脚本支持...

22110
来自专栏大内老A

通过扩展改善ASP.NET MVC的验证机制[使用篇]

ASP.NET MVC提供一种基于元数据的验证方式是我们可以将相应的验证特性应用到作为Model实体的类型或者属性/字段上,但是这依然具有很多的不足。在这篇文章...

20050
来自专栏大内老A

ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)

ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需...

20050

扫码关注云+社区

领取腾讯云代金券