代码之家  ›  专栏  ›  技术社区  ›  Neo

找到多个与控制器匹配的类型

  •  2
  • Neo  · 技术社区  · 10 年前

    我在努力 api versioning 使用 header 但在 different folder structure 如下图所示。

    在里面 Controller folder V1 其中的子文件夹 CustomerController.cs

    在里面 控制器文件夹 V2 其中的子文件夹 客户控制器.cs

    当我使用 URL 以上工作正常。

    我的问题是当我尝试这种方法时 收割台 它给了我以下错误:

    {“消息”:“发生错误。”,“异常消息”: “发现多个类型与名为“customer”的控制器匹配。 如果服务此请求的路由 ('api/{controller}/{id}')找到多个用 名称相同但命名空间不同,这是不受支持的。\r\n\r\n 对“customer”的请求已找到以下匹配项 控制器:\r\nPiVersion.Controller.V1.CustomerController\nPiVersion.Controller.V2.CustomeerController“,”ExceptionType“:”系统。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 }
                );
            }
    

    自定义控制器选择器.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 回复  |  直到 10 年前
        1
  •  1
  •   Amit Kumar Ghosh    10 年前

    我试着跟随。截至目前有效-

    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中。中国-

    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