找到了多种与控制器匹配的类型
Posted
技术标签:
【中文标题】找到了多种与控制器匹配的类型【英文标题】:Multiple types were found that match the controller 【发布时间】:2016-01-11 06:46:42 【问题描述】:我正在尝试使用header
来api versioning
,但在different folder structure
中,如下所示。
在Controller folder
中有V1
子文件夹在CustomerController.cs
和
在Controller folder
中有V2
子文件夹在CustomerController.cs
内
当我使用上面的URL
使用 api 版本时工作正常。
我的问题是当我使用header
尝试这种方法时,它给了我以下错误:
"Message": "发生错误。", "ExceptionMessage": “找到了与名为‘客户’的控制器匹配的多种类型。 如果服务此请求的路由会发生这种情况 ('api/controller/id') 找到了多个使用 名称相同但命名空间不同,这是不受支持的。\r\n\r\n 对“客户”的请求已找到以下匹配项 控制器:\r\nApiVersion.Controllers.V1.CustomerController\r\nApiVersion.Controllers.V2.CustomerController","ExceptionType":"System.InvalidOperationException","StackTrace":" 在 System.Web.Http.Dispatcher.DefaultHttpControllerSelector.SelectController(HttpRequestMessage 请求)\r\n 在 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;
【问题讨论】:
【参考方案1】:我试过跟随。截至目前工作 -
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
【讨论】:
不,我的电话就像http://localhost:58892/api/customer
和标题accept : application/json;version=1
你所做的是静态的:( 检查我的课程CustomeControllerSelector.cs
是的,当控制器位于控制器文件夹 CustomerV1Controller.cs
和 CustomerV2Controller.cs
并且代码为 var versionedControllerName = string.Concat(controllerName, "V", version); HttpControllerDescriptor versionedControllerDescriptor; if (controllers.TryGetValue(versionedControllerName, out versionedControllerDescriptor)) return versionedControllerDescriptor;
时,它工作正常
我的代码中的Webapi.Controllers
是什么我没有用过。
这是我的控制器命名空间的共同部分。您还需要更改路由代码以包含 route
部分。
我也在寻找同样的东西。如果找到会更新。以上是关于找到了多种与控制器匹配的类型的主要内容,如果未能解决你的问题,请参考以下文章
命名空间更改 - 找到与名为“Home”的控制器匹配的多种类型
找到了与名为“Home”的控制器匹配的多种类型 - 在两个不同的区域中