繁体   English   中英

如何通过名称空间限制Asp.net Web API / Owin对控制器的发现?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM