Skip to main content
 首页 » 编程设计

c#之使用 URL 在 Web Api 2 中进行 Controller 版本控制

2024年08月06日34me-sa

我想为我的 Controller 使用基于 URL 的版本控制。我找到的最佳解决方案是下面的代码。 我正在为此寻找更好的解决方案。我试过约束它没有用 也许我做错了什么我唯一关心的是在不同的命名空间中使用具有相同名称的 Controller ......?! 我使用字符串合并来创建想要的类型。这可能不是一个好主意。 如果您知道任何......请发送有关此主题的良好引用?

public class ControllerVersioning : DefaultHttpControllerSelector 
    { 
        private HttpConfiguration _config; 
        public ControllerVersioning(HttpConfiguration config) 
            : base(config) 
        { 
            _config = config; 
        } 
 
        public override HttpControllerDescriptor SelectController(HttpRequestMessage request) 
        { 
            var routeData = request.GetRouteData(); 
 
            var controllerName = routeData.Values["controller"].ToString(); 
            controllerName = char.ToUpper(controllerName[0]) + controllerName.Substring(1);  
            var versionName = routeData.Values["version"].ToString(); 
 
            HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(); 
            controllerDescriptor.Configuration = _config; 
            controllerDescriptor.ControllerName = controllerName; 
 
            string s = "ngolforoushan.Web.Api.Controllers.V" + versionName + "." + controllerName + "Controller"; 
            Type t=Type.GetType(s); 
            controllerDescriptor.ControllerType = t; 
 
            return controllerDescriptor; 
 
        } 
    } 

请您参考如下方法:

var dictionary = new Dictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase); 
 
    var assembliesResolver = _config.Services.GetAssembliesResolver(); 
    var controllerResolver = _config.Services.GetHttpControllerTypeResolver(); 
 
    var controllerTypes = controllerResolver.GetControllerTypes(assembliesResolver); 
 
    foreach (var cType in controllerTypes) 
    { 
        var segments = cType.Namespace.Split(Type.Delimiter); 
 
        var controllerName = cType.Name.Remove(cType.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length); 
 
        var controllerKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", segments[segments.Length - 1], controllerName); 
        if (!dictionary.Keys.Contains(controllerKey)) 
        { 
            dictionary[controllerKey] = new HttpControllerDescriptor(_config, cType.Name, cType); 
        } 
    } 

这是您可以返回程序集中所有 Controller 的列表并将它们全部放入字典的方式。

根据我上面的代码 - 我的意思是线程主题,我的第一篇文章 - 你知道如何获取 {version,controller} 和选择相关的 Controller 并将其作为参数传递。

我在下面添加了代码,以便更容易地获取版本和 Controller ,但是您需要知道您是否有不同的路由,它们与版本控制无关,您需要在分配版本和 Controller 字符串之前进行检查。

config.Routes.MapHttpRoute( 
            name: "DefaultApi", 
            routeTemplate: "api/{version}/{controller}/{id}", 
            defaults: new { id = RouteParameter.Optional } 
        );