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 = "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.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 "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<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[2].Value;
        }
    }
    return "1";
}

 


■ 使用SDammann.WebApi.Versioning

https://github.com/Sebazzz/SDammann.WebApi.Versioning

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值