webapi 版本控制
第一建立相应版本的文件夹
第二建立VersionControllerSelector
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;
namespace ScpWebsiteApi
{
public class VersionControllerSelector : DefaultHttpControllerSelector
{
private HttpConfiguration _config;
IDictionary<string, HttpControllerDescriptor> controllers = null;//缓存用
public VersionControllerSelector(HttpConfiguration config) : base(config)
{
_config = config;
}
//设计就是返回HttpControllerDesriptor的过程
public override System.Web.Http.Controllers.HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
//获取所有的controller键值集合
if (controllers == null)
{
GetControllerMapping();
}
//获取路由数据
var routeData = request.GetRouteData();
//从路由中获取当前controller的名称
var controllerName = (string)routeData.Values[“controller”];
//从url中获取到版本号
string verNum = Regex.Match(request.RequestUri.PathAndQuery, @”api/v(\d+)”).Groups[1].Value;
string key = string.Empty;
if (!string.IsNullOrEmpty(verNum))
{
key = controllerName + “v” + verNum;
}//获取Personv2
else
{
key = controllerName+verNum;
}
if (controllers.ContainsKey(key))//获取HttpControllerDescriptor
{
return controllers[key];
}
else
{
return null;
}
}
public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
{
Dictionary<string, HttpControllerDescriptor> dict
= new Dictionary<string, HttpControllerDescriptor>();
foreach (var asm in _config.Services.GetAssembliesResolver().GetAssemblies())
{
//获取所有继承自ApiController的非抽象类
var controllerTypes = asm.GetTypes()
.Where(t => !t.IsAbstract && typeof(ApiController).IsAssignableFrom(t)).ToArray();
foreach (var ctrlType in controllerTypes)
{
//从namespace中提取出版本号
var match = Regex.Match(ctrlType.Namespace,
@”ScpWebsiteApi.Controllers.App.v(\d+)”);
if (match.Success)
{
string verNum = match.Groups[1].Value;//获取版本号
string ctrlName = Regex.Match(ctrlType.Name, “(.+)Controller”).Groups[1].Value;//从PersonController中拿到Person
string key = ctrlName + “v” + verNum;//Personv2为key
dict[key] = new HttpControllerDescriptor(_config, ctrlName, ctrlType);
}
else
{
string ctrlName = Regex.Match(ctrlType.Name, “(.+)Controller”).Groups[1].Value;
string key = ctrlName ;
dict[key] = new HttpControllerDescriptor(_config, ctrlName, ctrlType);
}
}
}
controllers = dict;//因为项目启动的时候就会调用GetControllerMapping这个方法,这个方法主要是就获取所有的控制器,所以既然项目开始启动的时候就已经调用过这个方法了,已经获取到了所有的控制器了,为了避免我们在重新SelectController方法的时候二次调用,这里把已经取到的控制器字典缓存起来。
return dict;
}
}
}
第三在 WebApiConfig
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using System.Linq;
using System.Web;
using ScpWebsiteApi.Areas.HelpPage;
using System.Web.Http.Dispatcher;
namespace ScpWebsiteApi
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
// 将 Web API 配置为仅使用不记名令牌身份验证。
//config.SuppressDefaultHostAuthentication();
//config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
//config.Formatters.Remove(config.Formatters.FirstOrDefault(p => p.GetType() == typeof(System.Web.Http.ModelBinding.JQueryMvcFormUrlEncodedFormatter)));
config.SetDocumentationProvider(new XmlDocumentationProvider(HttpContext.Current.Server.MapPath(“~/App_Data/WebApiXML.xml”)));
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: “DefaultApi”,
routeTemplate: “api/{controller}/{action}”,
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: “DefaultApi1”,
routeTemplate: “api/{controller}/{id}”,
defaults: new { id = RouteParameter.Optional }
);
//根据版本号来注册路由:第v1版本的请求地址
config.Routes.MapHttpRoute(
name: “DefaultApiv1”,
routeTemplate: “api/v1/{controller}/{action}/{id}”,
defaults: new { id = RouteParameter.Optional }
);
// //根据版本号来注册路由:第v2版本的请求地址
// config.Routes.MapHttpRoute(
// name: “DefaultApiv2”,
// routeTemplate: “api/v2/{controller}/{action}/{id}”,
// defaults: new { id = RouteParameter.Optional }
// );
// config.Routes.MapHttpRoute(
// name: “DefaultApiv3”,
// routeTemplate: “api/v3/{controller}/{action}/{id}”,
// defaults: new { id = RouteParameter.Optional }
//);
////将自定义的VersionControllerSelector注册到系统中
config.Services.Replace(typeof(IHttpControllerSelector), new VersionControllerSelector(config));
}
}
}
最后请求