【问题标题】: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;
        }

【问题讨论】:

    标签: c# asp.net asp.net-web-api asp.net-web-api2 asp.net-web-api-routing


    【解决方案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 部分。
    • 我也在寻找同样的东西。如果找到会更新。
    猜你喜欢
    • 2023-03-28
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多