ASP.NET Web API中实现版本的几种方式
在ASP.NET Web API中,当我们的API发生改变,就涉及到版本问题了。如何实现API的版本呢?
1、通过路由设置版本
最简单的一种方式是通过路由设置,不同的路由,不同的版本,不同的controller。
config.Routes.MapHttpRoute(
name: "Food",
routeTemplate: "api/v1/nutrition/foods/{foodid}",
defaults:...
) config.Routes.MapHttpRoute(
name: "Foodv2",
routeTemplate: "api/v2/nutrition/foods/{foodid}",
defaults:...
)
2、通过HttpControllerSelector
通过更改HttpControllerSelector也可以实现。
首先写一个继承 DefaultHttpControllerSelector的类。
using System.Web.http.Dispatcher public class CountingKsControllerSelector : DefaultHttpControllerSelector
{
private HttpConfiguraion _config; public CountgKsControllerSelector(HttpConfiguraiton cofig) : base(config)
{
_config = config;
} //设计就是返回HttpControllerDesriptor的过程
public override System.Web.Http.Controllers.HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
//获取所有的controller键值集合
var controllers = GetControllerMapping(); //获取路由数据
var routeData = request.GetRouteData(); //从路由中获取当前controller的名称
var controllerName = (string)routeData.Values["controller"]; HttpControllerDescriptor descriptor; if(controllers.TryGetValue(controllerName, out descriptor))
{
var version = ""; //从QueryString中获取版本
var newName = string.Concat(controllerName, "V", version); HttpControllerDescriptor versionedDescriptor; if(controllers.TryGetValue(newName, out versionedDescriptor))
{
return versionedDescriptor;
} return descriptor;
} return null; }
}
在WebApiConfig.cs注册自定义的ControllerSelector
config.Services.Replace(typeof(IHttpControllerSelector), new CountingKsControllerSelector(config) );
以上是大致的实现思路。具体来说可以通过如下几种方式实现。
■ 通过Query String实现版本
客户端大致这样请求:
http://localhost:8901/api/nutrition/foods/4492/measures/7269?v=2
using System.Web.http.Dispatcher public class CountingKsControllerSelector : DefaultHttpControllerSelector
{
private HttpConfiguraion _config; public CountgKsControllerSelector(HttpConfiguraiton cofig) : base(config)
{
_config = config;
} //设计就是返回HttpControllerDesriptor的过程
public override System.Web.Http.Controllers.HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
//获取所有的controller键值集合
var controllers = GetControllerMapping(); //获取路由数据
var routeData = request.GetRouteData(); //从路由中获取当前controller的名称
var controllerName = (string)routeData.Values["controller"]; HttpControllerDescriptor descriptor; if(controllers.TryGetValue(controllerName, out descriptor))
{
//var version = "2"; //从QueryString中获取版本
var version = GetVersionFromQueryString(request); var newName = string.Concat(controllerName, "V", version); HttpControllerDescriptor versionedDescriptor; if(controllers.TryGetValue(newName, out versionedDescriptor))
{
return versionedDescriptor;
} return descriptor;
} return null; } //从QueryString中获取版本
private string GetVersionFromQueryString(HttpRequestMessage request)
{
var query = HttpUtility.ParseQueryString(request.RequestUri.Query);
var version = query["v"];
if(version != null)
{
return version;
} return "";
}
}
■ 通过Header实现版本
客户端大致这样请求:
User-Agent:Fiddler
Host:locahohost:8901
X-CountingKs-Version:2
private string GetVersionFromHeader(HttpRequestMessage request)
{
const string HEADER_NAME = "X-CountingKs-Version"; if(request.Headers.Contains(HEADER_NAME))
{
var header = request.Headers.GetValues(HEADER_NAME).FirstOrDefault(); if(header != null)
{
return header;
}
}
return "";
}
■ 通过Accept-Header实现版本
客户端大致这样请求:
User-Agent:Fiddler
Host:locahohost:8901
Accept: application/json;version=2
private string GetVersionFromAcceptHeaderVersion(HttpRequestMessage request)
{
var accept = request.Headers.Accept; foreach(var mime in accept)
{
if(mime.MediaType == "applicaiton/json")
{
var value = mime.Parameters
.Where(v => v.Name.Equals("version",StringComparison.OrdinalIngoreCase))
.FirstOrDefault(); return value.Value;
}
} return ""; }
■ 通过MediaType实现版本
在WebApiConfig.cs中
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); CreateMediaTypes(jsonFormatter); private static void CreateMediaTypes(JsonMediaTypeFormatter jsonFormatter)
{
var mediaTypes = new string[]
{
"application/vnd.counting,s.food.v1+json",
"application/vnd.countingks.measure.v1+json",
"application/vnd.countgks.measure.v2+json",
"applicatikon/vnd.countingks.diary.v1+json",
"application/vnd.countingks.diaryEntry.v1+json"
}; foreach(var mediaType in mediaTypes)
{
jsonFormatter.SupportedMeidaTypes.Add(new MediaTypeHeaderValue(mediaType));
}
}
在客户端大致这样请求:
User-Agent:Fiddler
Host:localhost:8901
Accept:application/vnd.countingks.food.v1+json
private string GetVersonFromMediaType(HttpRequestMessage request)
{
var accept = request.Headers.Accept;
var ex = new Regex(@"application\/vnd\.countingks\.([a-z]+)\.v([0-9]+)\+json". RegexOptions.IgnoreCase); foreach(var mime in accept)
{
var match = ex.Match(mime.MediaType);
if(match != null)
{
return match.Groups[].Value;
}
}
return "";
}
■ 使用SDammann.WebApi.Versioning
https://github.com/Sebazzz/SDammann.WebApi.Versioning
ASP.NET Web API中实现版本的几种方式的更多相关文章
- Asp.net Web API 返回Json对象的两种方式
这两种方式都是以HttpResponseMessage的形式返回, 方式一:以字符串的形式 var content = new StringContent("{\"FileName ...
- 在ASP.NET Web API中使用OData
http://www.alixixi.com/program/a/2015063094986.shtml 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在A ...
- ASP.NET WEB API 中的路由调试与执行过程跟踪
路由调试 RouteDebugger 是调试 ASP.NET MVC 路由的一个好的工具,在ASP.NET WEB API中相应的有 WebApiRouteDebugger ,Nuget安装 Inst ...
- ASP.NET Web API中使用OData
在ASP.NET Web API中使用OData 一.什么是ODataOData是一个开放的数据协议(Open Data Protocol)在ASP.NET Web API中,对于CRUD(creat ...
- ASP.NET Web API中的JSON和XML序列化
ASP.NET Web API中的JSON和XML序列化 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok ...
- ASP.NET Web API中的Controller
虽然通过Visual Studio向导在ASP.NET Web API项目中创建的 Controller类型默认派生与抽象类型ApiController,但是ASP.NET Web API框架本身只要 ...
- ASP.NET Web API 中的异常处理(转载)
转载地址:ASP.NET Web API 中的异常处理
- 【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化
谨以此文感谢关注此系列文章的园友!前段时间本以为此系列文章已没多少人关注,而不打算继续下去了.因为文章贴出来之后,看的人似乎不多,也很少有人对这些文章发表评论,而且几乎无人给予“推荐”.但前几天有人询 ...
- Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...
随机推荐
- tensorflow中的kernel/Adam 变量的来源
原因是使用Adam优化函数时,Adam函数会创建一个Adam变量,目的是保存你使用tensorflow创建的graph中的每个可训练参数的动量, words/_word_embeddings:0 bi ...
- Node.js模块定义总结
为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统.模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的.换言之,一个 Node.js 文件就是一个模块,这 ...
- TinyHttpd代码解析
十一假期,闲来无事.看了几个C语言开源代码.http://www.cnblogs.com/TinyHttpd 这里本来想解析一下TinyHttpd的代码,但是在网上一搜,发现前辈们已经做的很好了.这里 ...
- HDOJ题目分类
模拟题, 枚举1002 1004 1013 1015 1017 1020 1022 1029 1031 1033 1034 1035 1036 1037 1039 1042 1047 1048 104 ...
- Ueditor结合七牛云存储上传图片、附件和图片在线管理的实现和最新更新
最新下载地址: https://github.com/widuu/qiniu_ueditor_1.4.3 Ueditor七牛云存储版本 注意事项 老版本请查看 : https://github.com ...
- Using NHibernate with SQLite
The most convenient method to add NHibernate and SQLite for C# project is using NuGet. You can check ...
- #JS attr和prop的区别
HTML元素固有属性:使用prop方法 HTML元素自定义属性:使用attr方法
- 前端Datatables自定义事件(监听Datatables插件一些常见的事件动作)
今天开发项目的时候,用Datatables插件做前端分页列表,想在列表发生翻页.排序.搜索.改变单页显示数据条数这些行为的时候做一些其他的操作,看了半天Datatables官网终于找到可以监测到这些事 ...
- VS C++ 并发编程
1.VS2012及以上版本,支持C++11 thread类的并发编程. 相关材料可以参考博客:http://www.cnblogs.com/rangozhang/p/4468754.html 2.但对 ...
- CSS------让ul中高度不同的li底部对齐
如图: 代码:(需要将li中vertical-align属性设置为bottom) <ul style="margin-top:50px"> <li style=& ...