2025-04-21 14:10:27 +08:00

172 lines
7.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
//}
}
}