找到多个与控制器匹配的类型
Multiple types were found that match the controller
我正在尝试 api versioning
使用 header
但在 different folder structure
中,如下所示。
在 Controller folder
中 CustomerController.cs
中有 V1
子文件夹
和
在 Controller folder
中有 V2
子文件夹 CustomerController.cs
当我使用 api 版本使用上面的 URL
时工作正常。
我的问题是当我用 header
尝试这种方法时,出现以下错误:
{ "Message": "An error has occurred.", "ExceptionMessage":
"Multiple types were found that match the controller named 'customer'.
This can happen if the route that services this request
('api/{controller}/{id}') found multiple controllers defined with the
same name but differing namespaces, which is not supported.\r\n\r\nThe
request for 'customer' has found the following matching
controllers:\r\nApiVersion.Controllers.V1.CustomerController\r\nApiVersion.Controllers.V2.CustomerController", "ExceptionType": "System.InvalidOperationException", "StackTrace": "
at
System.Web.Http.Dispatcher.DefaultHttpControllerSelector.SelectController(HttpRequestMessage
request)\r\n at
System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"
}
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
CustomeControllerSelector.cs
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
var controllers = GetControllerMapping();
var routeData = request.GetRouteData();
var controllerName = routeData.Values["controller"].ToString();
//HttpControllerDescriptor controllerDescriptor;
var version = GetVersionFromAcceptHeaderVersion(request);
var controllerKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}",
version, controllerName);
//if (controllers.TryGetValue(controllerName, out controllerDescriptor))
// {
if (!string.IsNullOrEmpty(version))
{
HttpControllerDescriptor versionedControllerDescriptor;
if (controllers.TryGetValue(controllerKey, out versionedControllerDescriptor))
{
return versionedControllerDescriptor;
}
}
return null;
}
private string GetVersionFromAcceptHeaderVersion(HttpRequestMessage request)
{
var acceptHeader = request.Headers.Accept;
foreach (var mime in acceptHeader)
{
if (mime.MediaType == "application/json" || mime.MediaType == "text/html")
{
var version = mime.Parameters
.Where(v => v.Name.Equals("version", StringComparison.OrdinalIgnoreCase))
.FirstOrDefault();
if (version != null)
{
return version.Value;
}
return string.Empty;
}
}
return string.Empty;
}
我试过跟随。目前有效 -
public class CustomControllerSelector : DefaultHttpControllerSelector
{
//const string partName = "Webapi.Controllers";
private readonly HttpConfiguration _config;
public CustomControllerSelector(HttpConfiguration config)
: base(config)
{
_config = config;
}
public override System.Web.Http.Controllers.HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
var _route = request.GetRouteData();
var controllerName = base.GetControllerName(request);
var type = _config.Services.GetAssembliesResolver();
var controlles = _config.Services.GetHttpControllerTypeResolver().GetControllerTypes(type);
object name;
_route.Values.TryGetValue("route", out name);
//No more hard coding
var partName = controllers.FirstOrDefault().Namespace;
var st = name as string;
if (st != null)
{
var conType = controlles.FirstOrDefault(a => a.Namespace == string.Format("{0}.{1}", partName, st));
if (conType != null)
return new System.Web.Http.Controllers.HttpControllerDescriptor(_config, controllerName, conType);
}
return base.SelectController(request);
}
}
在WebApiConfig.cs-
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{route}/{id}",
defaults: new { id = RouteParameter.Optional }
);
测试路线 -
http://localhost:60957/api/Another/Route/a
http://localhost:60957/api/Another/Route2/aaaaa
我正在尝试 api versioning
使用 header
但在 different folder structure
中,如下所示。
在 Controller folder
中 CustomerController.cs
中有 V1
子文件夹
和
在 Controller folder
中有 V2
子文件夹 CustomerController.cs
当我使用 api 版本使用上面的 URL
时工作正常。
我的问题是当我用 header
尝试这种方法时,出现以下错误:
{ "Message": "An error has occurred.", "ExceptionMessage": "Multiple types were found that match the controller named 'customer'. This can happen if the route that services this request ('api/{controller}/{id}') found multiple controllers defined with the same name but differing namespaces, which is not supported.\r\n\r\nThe request for 'customer' has found the following matching controllers:\r\nApiVersion.Controllers.V1.CustomerController\r\nApiVersion.Controllers.V2.CustomerController", "ExceptionType": "System.InvalidOperationException", "StackTrace": " at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.SelectController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()" }
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
CustomeControllerSelector.cs
public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
var controllers = GetControllerMapping();
var routeData = request.GetRouteData();
var controllerName = routeData.Values["controller"].ToString();
//HttpControllerDescriptor controllerDescriptor;
var version = GetVersionFromAcceptHeaderVersion(request);
var controllerKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}",
version, controllerName);
//if (controllers.TryGetValue(controllerName, out controllerDescriptor))
// {
if (!string.IsNullOrEmpty(version))
{
HttpControllerDescriptor versionedControllerDescriptor;
if (controllers.TryGetValue(controllerKey, out versionedControllerDescriptor))
{
return versionedControllerDescriptor;
}
}
return null;
}
private string GetVersionFromAcceptHeaderVersion(HttpRequestMessage request)
{
var acceptHeader = request.Headers.Accept;
foreach (var mime in acceptHeader)
{
if (mime.MediaType == "application/json" || mime.MediaType == "text/html")
{
var version = mime.Parameters
.Where(v => v.Name.Equals("version", StringComparison.OrdinalIgnoreCase))
.FirstOrDefault();
if (version != null)
{
return version.Value;
}
return string.Empty;
}
}
return string.Empty;
}
我试过跟随。目前有效 -
public class CustomControllerSelector : DefaultHttpControllerSelector
{
//const string partName = "Webapi.Controllers";
private readonly HttpConfiguration _config;
public CustomControllerSelector(HttpConfiguration config)
: base(config)
{
_config = config;
}
public override System.Web.Http.Controllers.HttpControllerDescriptor SelectController(HttpRequestMessage request)
{
var _route = request.GetRouteData();
var controllerName = base.GetControllerName(request);
var type = _config.Services.GetAssembliesResolver();
var controlles = _config.Services.GetHttpControllerTypeResolver().GetControllerTypes(type);
object name;
_route.Values.TryGetValue("route", out name);
//No more hard coding
var partName = controllers.FirstOrDefault().Namespace;
var st = name as string;
if (st != null)
{
var conType = controlles.FirstOrDefault(a => a.Namespace == string.Format("{0}.{1}", partName, st));
if (conType != null)
return new System.Web.Http.Controllers.HttpControllerDescriptor(_config, controllerName, conType);
}
return base.SelectController(request);
}
}
在WebApiConfig.cs-
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{route}/{id}",
defaults: new { id = RouteParameter.Optional }
);
测试路线 -
http://localhost:60957/api/Another/Route/a
http://localhost:60957/api/Another/Route2/aaaaa