172 lines
7.2 KiB
C#
172 lines
7.2 KiB
C#
|
using System;
|
|||
|
using System.Collections.Concurrent;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Linq;
|
|||
|
using System.Net;
|
|||
|
using System.Net.Http;
|
|||
|
using System.Reflection;
|
|||
|
using System.Text;
|
|||
|
using System.Web;
|
|||
|
using System.Web.Http;
|
|||
|
using System.Web.Http.Controllers;
|
|||
|
using System.Web.Http.Dispatcher;
|
|||
|
using System.Web.Http.Routing;
|
|||
|
|
|||
|
namespace SwashbuckleEx.WebApiTest.Selectors
|
|||
|
{
|
|||
|
public class ClassifiedHttpControllerSelector:DefaultHttpControllerSelector
|
|||
|
{
|
|||
|
private const string AreaRouteVariableName = "area";
|
|||
|
private const string CategoryRouteVariableName = "category";
|
|||
|
private const string TheFixControllerFolderName = "Controllers";
|
|||
|
|
|||
|
private readonly HttpConfiguration _configuration;
|
|||
|
private readonly Lazy<ILookup<string, Type>> _apiControllerTypes;
|
|||
|
|
|||
|
private ILookup<string, Type> ApiControllerTypes;
|
|||
|
|
|||
|
public ClassifiedHttpControllerSelector(HttpConfiguration configuration) : base(configuration)
|
|||
|
{
|
|||
|
_configuration = configuration;
|
|||
|
_apiControllerTypes=new Lazy<ILookup<string, Type>>(GetApiControllerTypes);
|
|||
|
}
|
|||
|
|
|||
|
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
|
|||
|
{
|
|||
|
//return GetApiController(request);
|
|||
|
HttpControllerDescriptor des = null;
|
|||
|
string controllerName = this.GetControllerName(request);
|
|||
|
if (!string.IsNullOrWhiteSpace(controllerName))
|
|||
|
{
|
|||
|
var groups = this.ApiControllerTypes[controllerName.ToLower()];
|
|||
|
if (groups != null && groups.Any())
|
|||
|
{
|
|||
|
string endString;
|
|||
|
var routeDic = request.GetRouteData().Values;//存在controllerName的必定取到IHttpRouteData
|
|||
|
if (routeDic.Count > 1)
|
|||
|
{
|
|||
|
StringBuilder sb=new StringBuilder();
|
|||
|
foreach (var key in routeDic.Keys)
|
|||
|
{
|
|||
|
sb.Append(".");
|
|||
|
sb.Append(routeDic[key]);
|
|||
|
if (key.Equals(DefaultHttpControllerSelector.ControllerSuffix,
|
|||
|
StringComparison.CurrentCultureIgnoreCase))
|
|||
|
{
|
|||
|
//如果是Control,则代表命名空间结束
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
sb.Append(DefaultHttpControllerSelector.ControllerSuffix);
|
|||
|
endString = sb.ToString();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
endString = string.Format(".{0}{1}", controllerName,
|
|||
|
DefaultHttpControllerSelector.ControllerSuffix);
|
|||
|
}
|
|||
|
// 取NameSpace节点数最少的类型
|
|||
|
var type =
|
|||
|
groups.Where(t => t.FullName.EndsWith(endString, StringComparison.CurrentCultureIgnoreCase))
|
|||
|
.OrderBy(t => t.FullName.Count(s => s == '.'))
|
|||
|
.FirstOrDefault();//默认返回命名空间节点数最少的第一
|
|||
|
if (type != null)
|
|||
|
{
|
|||
|
des=new HttpControllerDescriptor(this._configuration,controllerName,type);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (des == null)
|
|||
|
{
|
|||
|
throw new HttpResponseException(request.CreateErrorResponse(HttpStatusCode.NotFound,
|
|||
|
string.Format("No route providing a controller name was found to match request URI '{0}'",
|
|||
|
request.RequestUri)));
|
|||
|
}
|
|||
|
return des;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private static string GetRouteValueByName(HttpRequestMessage request, string routeName)
|
|||
|
{
|
|||
|
IHttpRouteData data = request.GetRouteData();
|
|||
|
if (data.Values.ContainsKey(routeName))
|
|||
|
{
|
|||
|
return data.Values[routeName] as string;
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
//private static ConcurrentDictionary<string, Type> GetAllControllerTypes()
|
|||
|
//{
|
|||
|
// Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|||
|
// Dictionary<string, Type> types =
|
|||
|
// assemblies.SelectMany(
|
|||
|
// x =>
|
|||
|
// x.GetTypes()
|
|||
|
// .Where(
|
|||
|
// t =>
|
|||
|
// !t.IsAbstract &&
|
|||
|
// t.Name.EndsWith(ControllerSuffix, StringComparison.OrdinalIgnoreCase) &&
|
|||
|
// typeof(IHttpController).IsAssignableFrom(t))).ToDictionary(t => t.FullName, t => t);
|
|||
|
// return new ConcurrentDictionary<string, Type>(types);
|
|||
|
//}
|
|||
|
|
|||
|
private ILookup<string, Type> GetApiControllerTypes()
|
|||
|
{
|
|||
|
IAssembliesResolver assembliesResolver = this._configuration.Services.GetAssembliesResolver();
|
|||
|
return
|
|||
|
this._configuration.Services.GetHttpControllerTypeResolver()
|
|||
|
.GetControllerTypes(assembliesResolver)
|
|||
|
.ToLookup(
|
|||
|
t =>
|
|||
|
t.Name.ToLower()
|
|||
|
.Substring(0, t.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length),
|
|||
|
t => t);
|
|||
|
}
|
|||
|
|
|||
|
//private HttpControllerDescriptor GetApiController(HttpRequestMessage request)
|
|||
|
//{
|
|||
|
// string areaName = GetRouteValueByName(request, AreaRouteVariableName);
|
|||
|
// string categoryName = GetRouteValueByName(request, CategoryRouteVariableName);
|
|||
|
// string controllerName = GetControllerName(request);
|
|||
|
// Type type;
|
|||
|
// try
|
|||
|
// {
|
|||
|
// type = GetControllerType(areaName, categoryName, controllerName);
|
|||
|
// }
|
|||
|
// catch (Exception)
|
|||
|
// {
|
|||
|
// return null;
|
|||
|
// }
|
|||
|
// return new HttpControllerDescriptor(_configuration,controllerName,type);
|
|||
|
//}
|
|||
|
|
|||
|
//private Type GetControllerType(string areaName, string categoryName, string controllerName)
|
|||
|
//{
|
|||
|
// IEnumerable<KeyValuePair<string, Type>> query = _apiControllerTypes.Value.AsEnumerable();
|
|||
|
// string controllerSearchingName;
|
|||
|
// if (string.IsNullOrEmpty(areaName))
|
|||
|
// {
|
|||
|
// controllerSearchingName = TheFixControllerFolderName + "." + controllerName;
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// if (string.IsNullOrEmpty(categoryName))
|
|||
|
// {
|
|||
|
// controllerSearchingName = TheFixControllerFolderName + "." + areaName + "." + controllerName;
|
|||
|
// }
|
|||
|
// else
|
|||
|
// {
|
|||
|
// controllerSearchingName = TheFixControllerFolderName + "." + areaName + "." + categoryName + "." +
|
|||
|
// controllerName;
|
|||
|
// }
|
|||
|
// }
|
|||
|
// return
|
|||
|
// query.Where(x => x.Key.IndexOf(controllerSearchingName, StringComparison.OrdinalIgnoreCase) != -1)
|
|||
|
// .Select(x => x.Value)
|
|||
|
// .SingleOrDefault();
|
|||
|
//}
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
}
|