2016-06-08 76 views
0

在同一個項目中,我有兩個類似的啓動類是這樣的:如何通過名稱空間限制Asp.net Web API/Owin發現控制器?

namespace X.A 
{ 
    public class AStartup 
    { 
     public void Configuration(IAppBuilder appBuilder) 
     { 
      HttpConfiguration config = new HttpConfiguration(); 

      config.MapHttpAttributeRoutes(); 
      config.EnsureInitialized(); 

      appBuilder.UseWebApi(config); 
     } 
    } 
} 

namespace X.B 
{ 
    public class BStartup 
    { 
     public void Configuration(IAppBuilder appBuilder) 
     { 
      HttpConfiguration config = new HttpConfiguration(); 

      config.MapHttpAttributeRoutes(); 
      config.EnsureInitialized(); 

      appBuilder.UseWebApi(config); 
     } 
    } 
} 

我也有幾個控制器,有些是在命名空間XA ..:

namespace X.A.SomePlace 
{ 
    [RoutePrefix("A/SomeRouting")] 
    public class Controller1 : ApiController 
    { 
     [Route("SomeMethod")] 
     [HttpPost] 
     [ResponseType(typeof(SomeMethodResponse))] 
     public IHttpActionResult GetParameters([FromBody] SomeMethodRequest request) 
     { 
      // Some code 
     } 
    } 
} 

...和其他名稱空間XB ..:

namespace X.B.SomeOtherPlace 
{ 
    [RoutePrefix("B/AnotherRouting")] 
    public class Controller2 : ApiController 
    { 
     [Route("AnotherMethod")] 
     [HttpPost] 
     [ResponseType(typeof(AnotherMethodResponse))] 
     public IHttpActionResult AnotherMethod([FromBody] AnotherMethodRequest request) 
     { 
      // Another code 
     } 
    } 
} 

...和所有控制器都在同一個Asssembly中。

目前,各控制器自動的獲得註冊這兩個API。 我想,以限制命名空間中的控制器發現(即AStartup登記從X.A所有控制器....和BStartup登記從X.B所有控制器......)

有沒有辦法用MapHttpAttributeRoutes做到這一點?

我會還高興不使用屬性的路由另一種方法(即如果你有一個方法,在那裏我有編程,以明確地登記每個控制器,將工作對我罰款)。

回答

1

對PECO答案之後,我發現WEB API服務這裏的整個列表: http://www.asp.net/web-api/overview/advanced/configuring-aspnet-web-api

答案是實現其簡潔的http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection描述定製IHttpControllerTypeResolver。

我也發現了很多靈感在http://www.strathweb.com/2013/08/customizing-controller-discovery-in-asp-net-web-api/

如果這是對別人有用的,這裏是我使用的IHttpControllerTypeResolver:

namespace X.A 
{ 
    public class AControllerTypeResolver : DefaultHttpControllerTypeResolver 
    { 
     public AControllerTypeResolver() : base(IsHttpEndpoint) 
     { 
     } 

     private static bool IsHttpEndpoint(Type t) 
     {  
      if (t == null) throw new ArgumentNullException("t"); 

      return t.IsClass && 
       t.IsVisible && 
       !t.IsAbstract && 
       typeof(ABaseController).IsAssignableFrom(t); 
     } 
    } 
} 

而且我做了BControllerTypeResolver相同。

我不喜歡這個替換AStartup的默認服務:

config.Services.Replace(typeof(IHttpControllerTypeResolver), new AControllerTypeResolver()); 

我也必須確保我的所有控制器都從ABaseController(分別BBaseController)獲得。

是建關PECO的結構
1

我不知道該怎麼做,與屬性的路由。但是,如果您想使用正常路線,則可以實施自定義IAssembliesResolver(默認掃描控制器的當前appdomain中的所有程序集)。

public class CustomAssemblyResolver : IAssembliesResolver 
{ 
    private readonly Assembly[] _assemblies; 

    public CustomAssemblyResolver(params Assembly[] assemblies) 
    { 
     _assemblies = assemblies; 
    } 

    public ICollection<Assembly> GetAssemblies() 
    { 
     return _assemblies; 
    } 
} 

然後例如在AStartup你可以使用這個像這樣:

public class AStartup 
{ 
    public void Configuration(IAppBuilder appBuilder) 
    { 
     HttpConfiguration config = new HttpConfiguration(); 

     config.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver(typeof(Controller1).Assembly)); 

     config.EnsureInitialized(); 

     appBuilder.UseWebApi(config); 
    } 
} 
+0

各種控制器有不同的名稱空間,但都在同一個程序集(將更新問題以反映此)。你認爲仍然可以使用CustomAssemblyResolver來實現這個過濾嗎? – Ramsey

+0

嗯,不確定。他們不能在不同的集會中有一個原因嗎? – peco

0

拉姆齊的回答爲我工作。

就我而言,我曾與多個OWIN app.map'd類庫web.api項目託管MVC/API項目。我認爲標準

config.MapHttpAttributeRoutes(); 

導致衝突的路線試圖註冊不同的api項目之間。現在,每個OWIN api和託管應用程序的API都在其繼承的名稱空間內擁有自己的BaseApiController。每個BaseApiController都有Ramsey的ControllerTypeResolver。 OWIN項目做自己WebApiConfig設置,但現在的屬性路線註冊是這樣的:

apiConfig.Services.Replace(typeof(System.Web.Http.Dispatcher.IHttpControllerTypeResolver), new Core.Api.Controllers.RestrictedControllerTypeResolver()); 
apiConfig.MapHttpAttributeRoutes(); 

我測試了這一點,現在,當每個項目執行MapHttpAttributeRoutes它是它自己的項目中的控制器只映射路徑。

謝謝大家!

相關問題