using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; using System.Web; using System.Web.Http; using System.Web.Http.Controllers; using System.Web.Http.Dispatcher; using System.Web.Http.Routing; namespace MyCode.Project.WebApi.Providers { public class NamespaceHttpControllerSelector : DefaultHttpControllerSelector { private const string NamespaceRouteVariableName = "namespaces"; private readonly HttpConfiguration _configuration; private readonly Lazy> _apiControllerCache; /// /// 构造函数 /// /// public NamespaceHttpControllerSelector(HttpConfiguration configuration) : base(configuration) { _configuration = configuration; _apiControllerCache = new Lazy>(new Func>(InitializeApiControllerCache)); } /// /// 初始化ApiController实例 /// /// private ConcurrentDictionary InitializeApiControllerCache() { IAssembliesResolver assembliesResolver = this._configuration.Services.GetAssembliesResolver(); var types = this._configuration.Services.GetHttpControllerTypeResolver().GetControllerTypes(assembliesResolver).ToDictionary(t => t.FullName, t => t); return new ConcurrentDictionary(types); } /// /// 获取Controller全名 /// /// /// public IEnumerable GetControllerFullName(HttpRequestMessage request, string controllerName) { object namespaceName; var data = request.GetRouteData(); IEnumerable keys = _apiControllerCache.Value.ToDictionary, string, Type>(t => t.Key, t => t.Value, StringComparer.CurrentCultureIgnoreCase).Keys.ToList(); if (!data.Values.TryGetValue(NamespaceRouteVariableName, out namespaceName)) { return from k in keys where k.EndsWith(string.Format(".{0}{1}", controllerName, DefaultHttpControllerSelector.ControllerSuffix), StringComparison.CurrentCultureIgnoreCase) select k; } string[] namespaces = (string[])namespaceName; return from n in namespaces join k in keys on string.Format("{0}.{1}{2}", n, controllerName, DefaultHttpControllerSelector.ControllerSuffix).ToLower() equals k.ToLower() select k; } /// /// 获取Controller /// /// public override HttpControllerDescriptor SelectController(HttpRequestMessage request) { Type type; if (request == null) { throw new ArgumentNullException("request"); } string controllerName = this.GetControllerName(request); if (string.IsNullOrEmpty(controllerName)) { throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound, string.Format("无法通过API路由匹配到您所请求的URI '{0}'", new object[] { request.RequestUri }))); } IEnumerable fullNames = GetControllerFullName(request, controllerName); if (fullNames.Count() == 0) { throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound, string.Format("无法通过API路由匹配到您所请求的URI '{0}'", new object[] { request.RequestUri }))); } if (this._apiControllerCache.Value.TryGetValue(fullNames.First(), out type)) { return new HttpControllerDescriptor(_configuration, controllerName, type); } throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound, string.Format("无法通过API路由匹配到您所请求的URI '{0}'", new object[] { request.RequestUri }))); } /// /// 获取ControllerMapping /// /// public override IDictionary GetControllerMapping() { return _apiControllerCache.Value.ToDictionary(c => c.Key, c => new HttpControllerDescriptor(_configuration, c.Value.Name.Substring(0, c.Value.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length), c.Value), StringComparer.OrdinalIgnoreCase); } } }