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 ...
随机推荐
- Nagios配置文件nagios.cfg详解
这里开始要讲一些Nagios的配置. 首先要看看目前Nagios的主配置路径下有哪些文件.[root@nagios etc]# ll总用量 152-rwxrwxr-x. 1 nagios nagios ...
- linux根据端口查找进程【原创】
如转载请注明地址 1.利用lsof -i:端口号 lsof -i:端口号 [root@01 ~]# lsof -i:8097COMMAND PID USER FD TYPE DEVICE SIZE/O ...
- 关于 VS 2010 和 VS 2013 的警告 LNK4042
由于我最近调整了一下 Jimi 的文件结构,导致出现了一个 LNK4042 的 warning,我并没有很重视,这个 warning 导致出现了一些错误. 我调试了几个小时,一开始并没有想到是这个 w ...
- 过滤掉文本中的javascript标签代码
2014年1月21日 11:51:19 php代码: $content = preg_replace('#<\s*[script].*>#', '', $a);//有些攻击可以在scrip ...
- 查看library的依赖树
今天一同事问我如何解决包依赖重复的问题,我告诉他你可以用exclude,provide,compileOnly等关键字,他问我如何查找某个库依赖了什么,我说有一个插件,愣是想了好久没想起什么名字来,搜 ...
- 原生js实现ajax跨域(兼容IE8,IE9)
html设置meta标签兼容360兼容模式和IE怪异模式 <meta http-equiv="X-UA-Compatible" content="IE=9;IE=8 ...
- 上传文件异常问题 | 413 Request Entity Too Large
开发中遇到这样的问题:一个上传文件的功能,内网测试都正常了,但是发布到外网就无法上传大点的(大于1MB)文件,更奇怪的是,后台还没有任何的异常信息. 于是就用Http抓包工具(HttpDetect)看 ...
- 阿里云url解析,发布web后去除url中的端口号
归根结底就是80端口的使用,不是http的80 的 或 https的 都得加端口号 [问题描述] http://wisecores.wisers.com:8080/JsonProject/servl ...
- AndroidStudio3.0以上版本的坑
原文:https://blog.csdn.net/ytfunnysite/article/details/78864556 1.Error:Failed to resolve: com.android ...
- 一份可以发布jar包到MAVEN中央仓库的POM
[2017-01-03 更新]将基础的pom抽离成一个项目无关的parent pom,euler-framework的pom继承这个parent pom 今天在家折腾了一下怎么把Jar包发布到Mave ...