博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET Web API中实现版本的几种方式
阅读量:7122 次
发布时间:2019-06-28

本文共 6006 字,大约阅读时间需要 20 分钟。

 

在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.Dispatcherpublic 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 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.Dispatcherpublic 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 "1";    }}

 

■ 通过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 "1";}

 

■ 通过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 "1";    }

 

■ 通过MediaType实现版本

在WebApiConfig.cs中

 

var jsonFormatter = config.Formatters.OfType
().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[2].Value;        }    }    return "1";}

 

■ 使用SDammann.WebApi.Versioning
https://github.com/Sebazzz/SDammann.WebApi.Versioning

 

转载地址:http://nuael.baihongyu.com/

你可能感兴趣的文章
webpack
查看>>
js函数
查看>>
access token
查看>>
爬虫神器pyppeteer,对 js 加密降维打击
查看>>
吃鸡数据不完全分析
查看>>
iOS上下联动框架(Swift)
查看>>
Android RxJava之变换操作符(三)
查看>>
高性能 Web 缓存服务器 nuster 1.7.9.4 发布
查看>>
Java中基本类型占字节数以及Uint32的意思
查看>>
java后台框架 springmvc整合mybatis框架源码 java图片爬虫 bootstrap html5
查看>>
APK体积优化的一些总结
查看>>
Timer机制源码浅析
查看>>
javaScript之Location,Navigator,History
查看>>
RocketMQ中使用SQL92过滤消息
查看>>
Vue入门指南-02自定义全局和局部指令 (快速上手vue)
查看>>
Python知识点总结篇(一)
查看>>
介绍一款Java的方法入参校验工具
查看>>
三星7.0以上系统如何无需ROOT激活Xposed框架的步骤
查看>>
不借助第三个变量交换 a,b两个值
查看>>
[深入SystemUI]-了解recents的启动流程(一)
查看>>