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 ...
随机推荐
- Paint Fence
There is a fence with n posts, each post can be painted with one of the k colors.You have to paint a ...
- ispoweroftwo 判断2的次幂【转】
转自:https://www.cnblogs.com/troublelost/p/5236391.html 首先结果是: public bool IsPowerOfTwo(int n) { if(n& ...
- android的USB MTP && USB CDC/USBnet(ECM, NCM, ACM) && USB gardget
MTP的全称是Media Transfer Protocol(媒体传输协议),它是微软公司提出的一套媒体文件传输协议.早在智能手机普及前,数码相机和MP3播放器等都使用了MTP的前身PTP(Pictu ...
- apiCloud app调用浏览器打开网页的方法
在APP调用浏览器有两种方法:1.使用openApp2.使用openWin 两种方法调用浏览器后的效果有一点不同:1.使用openApp调用浏览器后,如果手机内有多个浏览器,会首先弹出选择浏览器的框2 ...
- 如何将同一个APP中的不同activity在Recent(最近任务)中显示?
需求描述 在应用Application1中存在A.B两个activity,当在应用启动了A.B activity,点击Recent键,如何让A.B两个activity都显示在Recent界面(最近任务 ...
- conda管理python包
参考:http://blog.sina.com.cn/s/blog_c3c116470102wlv5.html 查看python,numpy,scipy,matplotlib的版本及安装位置: htt ...
- 【oracle】入门学习(一)
一直想学oracle但都没有下定决心.这次借了书,一定要学好oracle. 目前学习 <Oracle从入门到精通> 明日科技 的Oracle 11g 版本 关系型数据库的基本理论 数据模型 ...
- oracle中循环读出一个表的信息插入到另外一个表中
declare cursor TAGENTMENUd is select * from TAGENTMENU where 1=1; -- 获取游标begin --遍历查询出的表 (注意 tn是整条记录 ...
- MySql存储过程中limit传参
最近做项目用到了MySQL数据库,感觉还是蛮好用的,但是有同事前几天写存储过程的时候老调不通,我看了看后发现把limit语句后面带的参数随便改成一个数字就调试通过了,不知道是MySql当初就这么设计的 ...
- synchronized和lock
Synchronized 同步代码块 使用 monitorenter 和 moniterexit 指令实现, monitorenter指令插入到同步代码块的开始位置, moniterexit 指令插 ...