webapi多版本控制
程序员文章站
2022-07-12 19:34:54
...
创建项目
1.选择一个.Net Framework的项目
2.创建一个空的ASp.Net web的应用程序,然后勾选旁边的web api,这只是简单的测试,后期可以直接选择web api
3.在Controllers中创建两个文件夹v1,v2,然后分别在文件中创建api控制器PosrtController(名称可以可以定义),创建完成后看下给控制有没有继承ApiController,然后分别加上一个简单的方法,返回值不同就可以,为后面的测试做准备。我这里为了简单就直接创建的空的控制器。
4.然后在项目中创建一个类VersionControllerSelectord,这个名称可以自己定义。创建完成后继承DefaultHttpControllerSelector的接口,然后类中写上如下代码;
public class VersionControllerSelector : DefaultHttpControllerSelector
{
private HttpConfiguration config;
private IDictionary<string, HttpControllerDescriptor> mCtrlMapping;
public VersionControllerSelector(HttpConfiguration config) : base(config)
{
this.config = config;
}
/// <summary>
/// 获取所有的controller,并注册
/// </summary>
/// <returns></returns>
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(e => !e.IsAbstract && typeof(ApiController).IsAssignableFrom(e)).ToArray();
//获取controller的名字
foreach (var ctrlType in controllerTypes)
{
string ctrlTypeNs = ctrlType.Namespace;
var match = Regex.Match(ctrlTypeNs, @"\.v(\d+)");
if (match.Success)
{
string verNum = match.Groups[1].Value;//把版本号中的数字提取出来
string ctrlTypeName = ctrlType.Name;//controller名字
var matchController = Regex.Match(ctrlTypeName, @"^(.+)Controller$");
if (!matchController.Success)
{
continue;
}
string ctrlName = matchController.Groups[1].Value;
string key = ctrlName + "v" + verNum;//个性约定
dict[key] = new HttpControllerDescriptor(config, ctrlName, ctrlType);
}
}
mCtrlMapping=dict;
}
return dict;
}
/// <summary>
/// 返回HttpControllerDescriptor的过程
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
string controller = (string)request.GetRouteData().Values["controller"];
if (mCtrlMapping == null) {
mCtrlMapping = GetControllerMapping();
}
var matchVer = Regex.Match(request.RequestUri.PathAndQuery, @"/v(\d+)/");
if (!matchVer.Success)
{
return base.SelectController(request);
}
string verNum = matchVer.Groups[1].Value;
string key = controller + "v" + verNum;
if (mCtrlMapping.ContainsKey(key))
{
return mCtrlMapping[key];
}
else
{
return base.SelectController(request);
}
}
}
5.最后就是修改WebApiConfig修改api的路由设置,
最关键就是最后一段代码,这段代码是显示多版本控制的关键。
config.Services.Replace(typeof(IHttpControllerSelector), new VersionControllerSelector(config));
6.最后我们在postman的中去测试一下