【问题标题】:Web api controller selection by route通过路由选择 Web api 控制器
【发布时间】:2017-04-15 01:35:21
【问题描述】:

我有两个不同的类库,其中包含相同名称的控制器。

namespace OldApiService{
   public class GreetingController: ApiController{
       public string Get(){ return "hello from old api"; }
   }
}

namespace NewApiService{
   public class GreetingController: ApiController{
       public string Get(){ return "hello from new api"; }
   }
}

我有一个主要的 We Api 应用程序,其中包含 Route 和其他辅助类。此应用程序引用 NewApiServiceOldApiService 程序集。

namespace MyApi {
    public class Startup 
    {            
        public void Configuration(IAppBuilder appBuilder) 
        { 
            HttpConfiguration config = new HttpConfiguration(); 
            config.Routes.MapHttpRoute( 
                name: "DefaultApi", 
                routeTemplate: "api/{api}/{controller}/{id}", 
                defaults: new { id = RouteParameter.Optional } 
            ); 

            appBuilder.UseWebApi(config); 
        } 
    } 
}

我想选择一个指定url参数的控制器。

http://localhost:4035/api/old/greeting 将使用 OldApiService 控制器

http://localhost:4035/api/new/greeting 将使用 NewApiService 控制器

我尝试更改 url 路由设置但没有成功。出现重复控制器错误。

有没有办法覆盖控制器选择机制。只需我将获取路由值(旧的或新的)并从指定的命名空间中选择控制器。

找到了与名为“greeting”的控制器匹配的多种类型。 如果服务此请求的路由会发生这种情况 ('api/{version}/{controller}/{id}') 发现定义了多个控制器 名称相同但命名空间不同,不支持。 “问候”的请求找到了以下匹配项 控制器:OldApiService.GreetingController NewApiService.GreetingController

我认为这是asp.net web api的一个重要问题。

【问题讨论】:

  • 如果你控制了这两个库,请考虑使用属性路由,因为通过基于约定的路由总是会发生冲突,因为它在映射路由时会查看控件名称。
  • 您是否尝试过使用 RoutePrefix 属性?
  • 是的,我尝试了 Route 属性但没有用
  • @bookmarker 显示您如何尝试 rout 属性。也包括 webapi 配置

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


【解决方案1】:

老图书馆

namespace OldApiService{

    public static class WebApiConfig {
        public static void Register(HttpConfiguration config) {
            config.config.MapHttpAttributeRoutes();        
        }
    }

   [RoutePrefix("api/old/greeting")]
   public class GreetingController: ApiController{
       [Route("")]
       public string Get(){ return "hello from old api"; }
   }
}

其他库

namespace NewApiService{

    public static class WebApiConfig {
        public static void Register(HttpConfiguration config) {
            config.config.MapHttpAttributeRoutes();        
        }
    }

   [RoutePrefix("api/new/greeting")]
   public class GreetingController: ApiController{
       [Route("")]
       public string Get(){ return "hello from new api"; }
   }
}

启动

namespace MyApi {

    public class Startup { 
        public void Configuration(IAppBuilder appBuilder) {

            var config = new HttpConfiguration(); 

            //Map attribute routes

            OldApiService.WebApiConfig.Register(config);
            NewApiService.WebApiConfig.Register(config);

            //convention-based routes
            config.Routes.MapHttpRoute( 
                name: "DefaultApi", 
                routeTemplate: "api/{api}/{controller}/{id}", 
                defaults: new { id = RouteParameter.Optional } 
            ); 

            appBuilder.UseWebApi(config); 
        } 
    } 

}

【讨论】:

    【解决方案2】:

    我会使用 RoutePrefix/Route 属性。

    namespace OldApiService{
       [RoutePrefix("api/old/greeting")]
       public class GreetingController: ApiController{
           [Route("")]
           public string Get(){ return "hello from old api"; }
       }
    }
    
    namespace NewApiService{
       [RoutePrefix("api/new/greeting")]
       public class GreetingController: ApiController{
           [Route("")]
           public string Get(){ return "hello from new api"; }
       }
    }
    

    【讨论】:

    • 记得还要展示如何公开两个库的配置
    • 找到了多个与名为“greeting”的控制器匹配的类型。如果为该请求提供服务的路由 ('api/{version}/{controller}/{id}') 发现多个控制器定义为同名但命名空间不同,则可能会发生这种情况,这是不受支持的。 'greeting' 请求找到了以下匹配的控制器: OldApiService.GreetingController NewApiService.GreetingController
    猜你喜欢
    • 1970-01-01
    • 2020-01-04
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 2016-07-12
    相关资源
    最近更新 更多