WebApi實現IHttpControllerSelector問題


一.讓Web API路由配置也支持命名空間參數
/// <summary>
    /// controller
    /// 選擇器
    /// </summary>
    public class ApiControllerSelerctor : IHttpControllerSelector
    {
        /// <summary>
        /// 版本信息
        /// </summary>
        private const string Version = "ERPVersion";
        private readonly HttpConfiguration _configuration;
        /// <summary>
        /// 延遲加載
        /// </summary>
        private readonly Lazy<Dictionary<string, HttpControllerDescriptor>> _controllers;
        private readonly HashSet<string> _duplicates;

        public ApiControllerSelerctor(HttpConfiguration config)
        {
            _configuration = config;
            _duplicates = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
            _controllers = new Lazy<Dictionary<string, HttpControllerDescriptor>>(InitializeController);
        }
        /// <summary>
        /// 通過返回基於命名空間的控制器描述符來實現查找
        /// </summary>
        /// <returns></returns>
        private Dictionary<string, HttpControllerDescriptor> InitializeController()
        {
            var dictionary = new Dictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase);
            IAssembliesResolver assembliesResolver = _configuration.Services.GetAssembliesResolver();
            IHttpControllerTypeResolver controllersResolver = _configuration.Services.GetHttpControllerTypeResolver();
            ICollection<Type> controllerTypes = controllersResolver.GetControllerTypes(assembliesResolver);
            if (controllerTypes != null)
            {
                foreach (Type t in controllerTypes)
                {
                    var segments = t.Namespace.Split(Type.Delimiter);
                    var controllerName = t.Name.Remove(t.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length);
                    string version = segments[segments.Length - 1];
                    var key = version.Equals("Controllers") ? string.Format(CultureInfo.InvariantCulture, "{0}", controllerName) : string.Format(CultureInfo.InvariantCulture, "{0}.{1}", version, controllerName);
                    if (dictionary.Keys.Contains(key))
                    {
                        _duplicates.Add(key);
                    }
                    else
                    {
                        dictionary[key] = new HttpControllerDescriptor(_configuration, t.Name, t);
                    }
                }
            }
            if (_duplicates != null)
            {
                foreach (string s in _duplicates)
                {
                    dictionary.Remove(s);
                }
            }
            return dictionary;
        }

        /// <summary>
        /// 從路由數據,獲取一個值
        /// 默認路由版本高於Controller
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="routeData"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        private static T GetRouteVariable<T>(IHttpRouteData routeData, string name)
        {
            object result = null;
            if (routeData.Values.TryGetValue(name, out result))
            {
                return (T)result;
            }
            return default(T);
        }

        /// <summary>
        /// 對應於自定義控制選擇器的命名空間,
        /// 將從HTTP請求消息中獲取命名空間和控制器
        /// 然后在字典中查找匹配的控制器
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            IHttpRouteData routeData = request.GetRouteData();
            if (routeData == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            //獲取版本號
            string version = GetRouteVariable<string>(routeData, Version);
            if (string.IsNullOrEmpty(version))
            {
                version = GetRequestVersion(request);
            }
            //從Route中讀取命名空間名稱和控制器名稱
            string controllerName = GetRouteVariable<string>(routeData, "controller");
            if (controllerName == null)
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            // 找到一個匹配的控制器
            string controller = string.IsNullOrEmpty(version) ? string.Format(CultureInfo.InvariantCulture, "{0}", controllerName) : string.Format(CultureInfo.InvariantCulture, "{0}.{1}", version, controllerName);

            HttpControllerDescriptor controllerDescriptor;
            if (_controllers.Value.TryGetValue(controller, out controllerDescriptor))
            {
                return controllerDescriptor;
            }
            else if (_duplicates.Contains(controller))
            {
                throw new HttpResponseException(
                    request.CreateErrorResponse(HttpStatusCode.InternalServerError,"請檢查路由配置"));
            }
            else
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
        }

        public IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
        {
            return _controllers.Value;
        }
        /// <summary>
        /// 獲取請求版本信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private string GetRequestVersion(HttpRequestMessage request)
        {
            if (request.Headers.Contains(Version))
            {
                var versionHeader = request.Headers.GetValues(Version).FirstOrDefault();
                if (versionHeader != null)
                {
                    return versionHeader;
                }
            }
            return string.Empty;
        }
    }

然后在WebApiConfig類的Register中替換服務即可實現

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM