在同一个项目中,我有两个类似的启动类:
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);
}
}
}
我还有几个控制器,其中一些是名称空间X.A ......:
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
}
}
}
...和其他人在命名空间X.B ......:
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做到这一点?
我也会对另一种不使用属性路由的方法感到满意(例如,如果你有一个方法,我必须以编程方式明确地注册每个控制器,这对我来说很合适。)
答案 0 :(得分: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);
}
}
答案 1 :(得分:1)
关于peco回答,我在这里找到了WEB API服务的完整列表: http://www.asp.net/web-api/overview/advanced/configuring-aspnet-web-api
答案是实现一个自定义的IHttpControllerTypeResolver,在http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection简洁描述。
我也在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)。
答案 2 :(得分:1)
Ramsey的回答是基于peco的结构为我工作。
就我而言,我有一个托管MVC / api项目,其中包含多个OWIN app.map的类库web.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时,它只映射自己项目中控制器的路径。
谢谢大家!