一旦成功的发布API后,使用者将依赖于你所提供的服务。但是变更总是无法避免的,因此谨慎的制定ASP.NET Web API的版本策略就变得非常重要。一般来说,新的功能需要无缝的接入,有时新老版本需要并行,以便给使用者足够的时间来进行迁移和配套的变更。设置,老的版本会一直持续被使用。

简单版本管理

假设我们现在对StudentsController进行修改,将GET方法中返回“FirstName” 和 “LastName”修改为返回“FullName”和 “CoursesDuration”。

最简单的方法就是新建一个类似于StudentsV2Controller的新服务。请留意V2,接下来将依赖这个引入管理策略。这种方法来自于Shawn Wildermuthplural sight course文章。旧版本的服务返回的json应该是这样的:

   1:  [{
   2:      "id": 2,
   3:      "url": "http://localhost:8323/api/students/HasanAhmad",
   4:      "firstName": "Hasan",
   5:      "lastName": "Ahmad",
   6:      "gender": 0,
   7:      "enrollmentsCount": 4
   8:  },
   9:  {
  10:      "id": 3,
  11:      "url": "http://localhost:8323/api/students/MoatasemAhmad",
  12:      "firstName": "Moatasem",
  13:      "lastName": "Ahmad",
  14:      "gender": 0,
  15:      "enrollmentsCount": 4
  16:  }]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

而新版本的返回如下:

   1:  [{
   2:      "id": 2,
   3:      "url": "http://localhost:8323/api/students/HasanAhmad",
   4:      "fullName": "Hasan Ahmad",
   5:      "gender": 0,
   6:      "enrollmentsCount": 4,
   7:      "coursesDuration": 13
   8:  },
   9:  {
  10:      "id": 3,
  11:      "url": "http://localhost:8323/api/students/MoatasemAhmad",
  12:      "fullName": "Moatasem Ahmad",
  13:      "gender": 0,
  14:      "enrollmentsCount": 4,
  15:      "coursesDuration": 16
  16:  }]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

新版本的GET函数的实现为:

   1:  public IEnumerable<StudentV2BaseModel> Get(int page = 0, int pageSize = 10)
   2:      {
   3:          IQueryable<Student> query;
   4:   
   5:          query = TheRepository.GetAllStudentsWithEnrollments().OrderBy(c => c.LastName);
   6:   
   7:          var totalCount = query.Count();
   8:          var totalPages = Math.Ceiling((double)totalCount / pageSize);
   9:   
  10:          var urlHelper = new UrlHelper(Request);
  11:          var prevLink = page > 0 ? urlHelper.Link("Students", new { page = page - 1, pageSize = pageSize }) : "";
  12:          var nextLink = page < totalPages - 1 ? urlHelper.Link("Students", new { page = page + 1, pageSize = pageSize }) : "";
  13:   
  14:          var paginationHeader = new
  15:          {
  16:              TotalCount = totalCount,
  17:              TotalPages = totalPages,
  18:              PrevPageLink = prevLink,
  19:              NextPageLink = nextLink
  20:          };
  21:   
  22:          System.Web.HttpContext.Current.Response.Headers.Add("X-Pagination",
  23:          Newtonsoft.Json.JsonConvert.SerializeObject(paginationHeader));
  24:   
  25:          var results = query
  26:          .Skip(pageSize * page)
  27:          .Take(pageSize)
  28:          .ToList()
  29:          .Select(s => TheModelFactory.CreateV2Summary(s));
  30:   
  31:          return results;
  32:      }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

StudentV2BaseModel和CreateV2Summary只是为了举例方便,实际可以根据需要是否要进行这样的修改或者无须修改。

具体的代码如下:

   1:  public class StudentV2BaseModel
   2:      {
   3:          public int Id { get; set; }
   4:          public string Url { get; set; }
   5:          public string FullName { get; set; }
   6:          public Data.Enums.Gender Gender { get; set; }
   7:          public int EnrollmentsCount { get; set; }
   8:          public double CoursesDuration { get; set; }
   9:      }
  10:   
  11:      public class ModelFactory
  12:      {
  13:          public StudentV2BaseModel CreateV2Summary(Student student)
  14:          {
  15:              return new StudentV2BaseModel()
  16:              {
  17:                  Url = _UrlHelper.Link("Students", new { userName = student.UserName }),
  18:                  Id = student.Id,
  19:                  FullName = string.Format("{0} {1}", student.FirstName, student.LastName),
  20:                  Gender = student.Gender,
  21:                  EnrollmentsCount = student.Enrollments.Count(),
  22:                  CoursesDuration = Math.Round(student.Enrollments.Sum(c => c.Course.Duration))
  23:              };
  24:          }
  25:      }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

来源:http://bitoftech.net/2013/12/16/asp-net-web-api-versioning-strategy/

[翻译]创建ASP.NET WebApi RESTful 服务(9)的更多相关文章

  1. [翻译]创建ASP.NET WebApi RESTful 服务(8)

    本章讨论创建安全的WebApi服务,到目前为止,我们实现的API都是基于未加密的HTTP协议,大家都知道在Web中传递身份信息必须通过HTTPS,接下来我们来实现这一过程. 使用HTTPS 其实可以通 ...

  2. [翻译]创建ASP.NET WebApi RESTful 服务(11)

    本章介绍通过使用Ali Kheyrollahi开发的CacheCow来实现服务器端的缓存.所有代码现在都可以在GitHub上下载. 我们将要实现的缓存方式叫做Conditional Requests, ...

  3. [翻译]创建ASP.NET WebApi RESTful 服务(7)

    实现资源分页 本章我们将介绍几种不同的结果集分页方式,实现手工分页,然后将Response通过两个不同的方式进行格式化(通过Response的Envelop元数据或header). 大家都知道一次查询 ...

  4. [翻译]创建ASP.NET WebApi RESTful 服务(10)

    通过URI实现版本管理 另一种实现版本管理的方式就是通过URI来进行处理,类似于http://localhost:{your_port}/api/v1/students/.这种方式的好处是使用者可以清 ...

  5. IIS 部署ASP.Net, WebAPI, Restful API, PUT/DELETE 报405错解决办法, webapi method not allowed 405

    WebDAV 是超文本传输协议 (HTTP) 的一组扩展,为 Internet 上计算机之间的编辑和文件管理提供了标准.利用这个协议用户可以通过Web进行远程的基本文件操作,如拷贝.移动.删除等.在I ...

  6. Asp.net WebAPi Restful 的实现和跨域

    现在实际开发中用webapi来实现Restful接口开发很多,我们项目组前一段时间也在用这东西,发现大家用的还是不那么顺畅,所以这里写一个Demo给大家讲解一下,我的出发点不是如何实现,而是为什么? ...

  7. 在windows10上创建ASP.NET mvc5+Memcached服务

    感谢两位两位大佬: https://blog.csdn.net/l1028386804/article/details/61417166 https://www.cnblogs.com/running ...

  8. ASP.NET WebAPI 双向token实现对接小程序登录逻辑

    最近在学习用asp.net webapi搭建小程序的后台服务,因为基于小程序端和后台二者的通信,不像OAuth(开放授权),存在第三方应用.所以这个token是双向的,一个是对用户的,一个是对接口的. ...

  9. [03-2]VS2017 创建 ASP.NET Core Web 程序

    VS2017 创建 ASP.NET Core Web 程序 本文作者:梁桐铭- 微软最有价值专家(Microsoft MVP) 文章会随着版本进行更新,关注我获取最新版本 本文出自<从零开始学 ...

随机推荐

  1. STL头文件

    #include <iostream>标准输入输出cin cout等 #include <algorithm> 算法库 如sort find等 #include <vec ...

  2. jquery来跨域提交表单

    说说用jquery来实现跨域提交表单 在jQuery中,我们使用json数据类型,通过getJSON方法来实现从服务端获取或发送数据,而当要向不同远程服务器端提交或者获取数据时,要采用jsonp数据类 ...

  3. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

    上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...

  4. (六)6.8 Neurons Networks implements of PCA ZCA and whitening

    PCA 给定一组二维数据,每列十一组样本,共45个样本点 -6.7644914e-01  -6.3089308e-01  -4.8915202e-01 ... -4.4722050e-01  -7.4 ...

  5. 【Android】跟着教程做の学习笔记

    教程 + <第一行代码 - Android> //尽量在十二月底学完吧(同步学习java基础)

  6. 模拟实现死亡之Ping(Ping of death)

    需求描述 使用hping构造IP分片,模拟实现死亡之Ping 环境搭建 使用VMWare和Dynamips. 实现思路 构造重装后大于65535字节的IP分片 hping 192.168.1.1 -1 ...

  7. Pig实战

    1. pig简介 2. 安装pig 3. 实战pig 4. 深入pig 5. 参考资料及代码下载 <1>. Pig简介  pig是hadoop项目的一个拓展项目, 用以简化hadoop编程 ...

  8. python tile函数用法

    tile函数位于python模块 numpy.lib.shape_base中,他的功能是重复某个数组.比如tile(A,n),功能是将数组A重复n次,构成一个新的数组,我们还是使用具体的例子来说明问题 ...

  9. svn sc create 命令行创建服务自启动

    今天重装了系统,Subversion服务也得重装.照例输入代码: sc create svnserve binpath="d:\PortableApps\svn\svnserve.exe - ...

  10. mipmap 目录和drawable 目录有什么区别

    Q :最近使用studio 发现drawle-hdpi 都没有了换成了mipmap-hdpi,这两个目录有什么区别呢,哪个比较好呢??? A: 我简单总结一下: 使用上没有任何区别,你把它当drawa ...