2016-06-08 78 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它是它自己的项目中的控制器只映射路径。

谢谢大家!

相关问题