博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET Web API编程——版本控制
阅读量:4696 次
发布时间:2019-06-09

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

版本控制

 

版本控制的方法有很多,这里提供一种将Odata与普通web api版本控制机制统一的方法,但也可以单独控制,整合控制与单独控制主要的不同是:整合控制通过VersionControllerSelector来选择控制器过滤器,而不是直接选择控制器。

 采用此机制来控制版本,应按照如下规则命名控制器:

自定义标识符+版本+Controller

自定义标识符:能体现控制器含义的字符串

版本:表示版本的字符串,例如:V1,V1.0;不建议使用V1.0这样的写法,因为这样控制器名称会相当怪异,如果表示小版本号,那么可以使用V1D0,这种写法,即用一个字母代替句号。

命名空间对应了项目文件的组织形式,控制器的命名空间为:

1 Odata版本控制

扩展DefaultHttpControllerSelector

public class ODataVersionControllerSelector : DefaultHttpControllerSelector{        public Dictionary
RouteVersionSuffixMapping { get; set; } public ODataVersionControllerSelector(HttpConfiguration configuration) : base(configuration) { if (RouteVersionSuffixMapping == null) { RouteVersionSuffixMapping = new Dictionary
(); } } public override string GetControllerName(HttpRequestMessage request) { var controllerName = base.GetControllerName(request); if (string.IsNullOrEmpty(controllerName)) { return controllerName; } var routeName = request.ODataProperties().RouteName; if (string.IsNullOrEmpty(routeName)) { return controllerName; } var mapping = GetControllerMapping(); if (!RouteVersionSuffixMapping.ContainsKey(routeName)) { return controllerName; } var versionControllerName = controllerName + RouteVersionSuffixMapping[routeName]; return mapping.ContainsKey(versionControllerName) ? versionControllerName : controllerName; }}

修改WebApiConfig.Register方法

public static class WebApiConfig{  public static void Register(HttpConfiguration config)  {      ......      //odata路由            config.MapODataServiceRoute(                           routeName: "V1OdataRouteVersioning",                           routePrefix: "Odata/V1",                           model: GetEdmModel());            config.Count().Filter().OrderBy().Expand().Select().MaxTop(null);            config.AddODataQueryFilter();            config.Services.Replace(typeof(IHttpControllerSelector), new ODataVersionControllerSelector (config));            var controllerSelector = config.Services.GetService(typeof(IHttpControllerSelector)) as ODataVersionControllerSelector ;       controllerSelector.RouteVersionSuffixMapping.Add("V1OdataRouteVersioning", "V1");        ......  }}private static IEdmModel GetEdmModel(){  ODataConventionModelBuilder builder = new ODataConventionModelBuilder();  #region Publication  var publicationsSet = builder.EntitySet
("Publications").EntityType.Collection;  var getPublicationsFunction = publicationsSet.Function("GetPublications").Returns
();  getPublicationsFunction.Parameter
("userId"); publicationsSet.Action("AddPublication").Returns
().Parameter
("publicationAddBM");  publicationsSet.Action("DeletePublication").Returns
().Parameter
("publicationDelBM"); #endregion  builder.Namespace = "Service";  return builder.GetEdmModel();}

2 普通Api版本控制

 

扩展IHttpControllerSelector

public class NormalVersionControllerSelector : IHttpControllerSelector{        private const string Version = "version";        private const string ControllerKey = "controller";        private readonly HttpConfiguration _configuration;        private readonly Lazy
> _controllers; private readonly HashSet
_duplicates; public NormalVersionControllerSelector(HttpConfiguration config) { _configuration = config; _duplicates = new HashSet
(StringComparer.OrdinalIgnoreCase); _controllers = new Lazy
>(InitializeControllerDictionary); } private Dictionary
InitializeControllerDictionary() { var dictionary = new Dictionary
(StringComparer.OrdinalIgnoreCase); IAssembliesResolver assembliesResolver = _configuration.Services.GetAssembliesResolver(); IHttpControllerTypeResolver controllersResolver = _configuration.Services.GetHttpControllerTypeResolver(); ICollection
controllerTypes = controllersResolver.GetControllerTypes(assembliesResolver); foreach (Type t in controllerTypes) { var segments = t.Namespace.Split(Type.Delimiter); //去掉HY_WebApi.V1.Controllers.KeyController中的HY_WebApi. //去掉HY_WebApi.HYDB.V1.Controllers.HYSearchController中的HY_WebApi.HYDB. //因此,保留V1.Controllers.KeyController这三部分 //键值格式如:V1.Controllers.KeyController string[] items = t.FullName.Split(new char[]{ '.'},StringSplitOptions.RemoveEmptyEntries); int count = items.Count(); var key = string.Format("{0}.{1}.{2}", items[count - 3], items[count - 2], items[count - 1]); // Check for duplicate keys. if (dictionary.ContainsKey(key)) { _duplicates.Add(key); } else { dictionary[key] = new HttpControllerDescriptor(_configuration, t.Name, t); } } return dictionary; } // Get a value from the route data, if present. private static T GetRouteVariable
(IHttpRouteData routeData, string name) { object result = null; if (routeData.Values.TryGetValue(name, out result)) { return (T)result; } return default(T); } public HttpControllerDescriptor SelectController(HttpRequestMessage request) { IHttpRouteData routeData = request.GetRouteData(); if (routeData == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } // Get the namespace and controller variables from the route data. string version = GetRouteVariable
(routeData, Version); if (version == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } string controllerName = GetRouteVariable
(routeData, ControllerKey); if (controllerName == null) { throw new HttpResponseException(HttpStatusCode.NotFound); } // 匹配控制器 string key = String.Format("{0}.Controllers.{1}{2}Controller", version, controllerName,version); HttpControllerDescriptor controllerDescriptor; if (_controllers.Value.TryGetValue(key, out controllerDescriptor)) { return controllerDescriptor; } else if (_duplicates.Contains(key)) { throw new HttpResponseException( request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Multiple controllers were found that match this request.")); } else { throw new HttpResponseException(HttpStatusCode.NotFound); } } public IDictionary
GetControllerMapping() { return _controllers.Value; } }}

修改WebApiConfig.Register方法

public static class WebApiConfig{        public static void Register(HttpConfiguration config)        {          ......        // Web API 路由            config.Routes.MapHttpRoute(                name: "defaultRoute",                routeTemplate: "api/{version}/{controller}/{action}/{id}",                defaults: new { id = RouteParameter.Optional }            );            config.Services.Replace(typeof(IHttpControllerSelector), new NormalVersionControllerSelector(config));         ......     }}

3 同时支持Odata,与普通Web Api版本控制

 

扩展DefaultHttpControllerSelector

public class VersionControllerSelector : DefaultHttpControllerSelector{        public Dictionary
RouteVersionSuffixMapping { get; set; } private HttpConfiguration configuration; public VersionControllerSelector(HttpConfiguration configuration) : base(configuration) { this.configuration = configuration; if (RouteVersionSuffixMapping == null) { RouteVersionSuffixMapping = new Dictionary
(); } } public override string GetControllerName(HttpRequestMessage request) { return SelectController(request).ControllerName; } public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { var routeName = request.ODataProperties().RouteName; if (!string.IsNullOrWhiteSpace(routeName)) {
//odata路由 var selector = new ODataVersionControllerSelector(configuration); selector.RouteVersionSuffixMapping = RouteVersionSuffixMapping; return selector.SelectController(request); } else {
//普通路由 var selector = new NormalVersionControllerSelector(configuration); return selector.SelectController(request); } }}修改WebApiConfig.Register方法public static class WebApiConfig public static void Register(HttpConfiguration config) {        // Web API 路由 config.Routes.MapHttpRoute( name: "defaultRoute", routeTemplate: "api/{version}/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); //odata路由 config.MapODataServiceRoute( routeName: "V1OdataRouteVersioning", routePrefix: "Odata/V1", model: GetEdmModel()); config.Count().Filter().OrderBy().Expand().Select().MaxTop(null); config.AddODataQueryFilter(); config.Services.Replace(typeof(IHttpControllerSelector), new VersionControllerSelector(config)); var controllerSelector = config.Services.GetService(typeof(IHttpControllerSelector)) as VersionControllerSelector; controllerSelector.RouteVersionSuffixMapping.Add("V1OdataRouteVersioning", "V1");    }}

其中GetEdmModel()方法与前述方法相同。

转载于:https://www.cnblogs.com/hdwgxz/p/7856619.html

你可能感兴趣的文章
最新版IntelliJ IDEA2019 破解教程(2019.08.07-情人节更新)
查看>>
我是怎么用缠论在商品里边抢钱之二 (2019-07-12 15:10:10)
查看>>
python入门之正则表达式
查看>>
SAS学习经验总结分享:篇五-过程步的应用
查看>>
Android创建文件夹及文件并写入数据
查看>>
file的getPath getAbsolutePath和getCanonicalPath的不同
查看>>
课时4—切入切出动画
查看>>
eclipse 编辑 python 中文乱码的解决方案
查看>>
Python 爬虫的集中简单方式
查看>>
数据库MySQL/mariadb知识点——触发器
查看>>
Ubuntu做Tomcat服务:insserv: warning: script 'tomcat' missing LSB tags and overrides
查看>>
Binary Agents
查看>>
入门Webpack,看这篇就够了
查看>>
如何在数据库中使用索引
查看>>
ring0
查看>>
windows虚拟机下 安装docker 踩过的坑
查看>>
使用 CXF 做 webservice 简单例子
查看>>
socket.io 消息发送
查看>>
C# 两个datatable中的数据快速比较返回交集或差集
查看>>
关于oracle样例数据库emp、dept、salgrade的mysql脚本复杂查询分析
查看>>