![](/img/trans.png)
[英]Controllers With Same Name In Different NameSpace ASP.NET WEB API
[英]How to restrict Asp.net Web API / Owin discovery of controllers by namespace?
在同一項目中,我有兩個類似的啟動類,如下所示:
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
}
}
}
...並且所有控制器都在同一個程序集中。
當前,所有控制器都自動注冊到兩個API。 我想按名稱空間限制控制器的發現(即AStartup從XA注冊所有控制器...,而BStartup從XB注冊所有控制器..)
有沒有辦法用MapHttpAttributeRoutes做到這一點?
對於不使用屬性路由的另一種方法,我也將感到滿意(例如,如果您有一種方法,我必須以編程方式顯式地注冊每個控制器,那對我來說將很好地工作)。
拉姆齊的答案建立在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時,它僅在其自己項目中映射控制器的路由。
感謝大家!
我不知道該如何使用屬性路由。 但是,如果您想使用常規路由,則可以實現自定義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);
}
}
在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)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.