102 lines
4.6 KiB
C#
102 lines
4.6 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Web;
|
||
using System.Web.Http.Dispatcher;
|
||
using System.Net.Http;
|
||
using System.Web.Http;
|
||
using System.Web.Http.Controllers;
|
||
using System.Net;
|
||
|
||
namespace MyCode.Project.WebApi.Providers
|
||
{
|
||
public class AreaHttpControllerSelector : DefaultHttpControllerSelector
|
||
{
|
||
private readonly HttpConfiguration _configuration;
|
||
/// <summary>
|
||
/// Lazy 当前程序集中包含的所有IHttpController反射集合,TKey为小写的Controller
|
||
/// </summary>
|
||
private readonly Lazy<ILookup<string, Type>> _apiControllerTypes;
|
||
private ILookup<string, Type> ApiControllerTypes
|
||
{
|
||
get
|
||
{
|
||
return this._apiControllerTypes.Value;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// Initializes a new instance of the AreaHttpControllerSelector class
|
||
/// </summary>
|
||
/// <param name="configuration"></param>
|
||
public AreaHttpControllerSelector(HttpConfiguration configuration)
|
||
: base(configuration)
|
||
{
|
||
this._configuration = configuration;
|
||
this._apiControllerTypes = new Lazy<ILookup<string, Type>>(this.GetApiControllerTypes);
|
||
}
|
||
/// <summary>
|
||
/// 获取当前程序集中 IHttpController反射集合
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
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);
|
||
}
|
||
/// <summary>
|
||
/// Selects a System.Web.Http.Controllers.HttpControllerDescriptor for the given System.Net.Http.HttpRequestMessage.
|
||
/// </summary>
|
||
/// <param name="request"></param>
|
||
/// <returns></returns>
|
||
public override HttpControllerDescriptor SelectController(HttpRequestMessage 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 tmp = new StringBuilder();
|
||
foreach (var key in routeDic.Keys)
|
||
{
|
||
tmp.Append('.');
|
||
tmp.Append(routeDic[key]);
|
||
if (key.Equals(DefaultHttpControllerSelector.ControllerSuffix, StringComparison.CurrentCultureIgnoreCase))
|
||
{//如果是control,则代表命名空间结束
|
||
break;
|
||
}
|
||
}
|
||
tmp.Append(DefaultHttpControllerSelector.ControllerSuffix);
|
||
endString = tmp.ToString();
|
||
}
|
||
else
|
||
{
|
||
endString = string.Format(".{0}{1}", controllerName, DefaultHttpControllerSelector.ControllerSuffix);
|
||
}
|
||
//取NameSpace节点数最少的Type
|
||
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;
|
||
}
|
||
}
|
||
} |