手动注册 WebApi 控制器

Manual registration of WebApi Controllers

我想在自托管 WebApi 时禁用自动发现控制器,并在 运行 时间手动指定控制器并将它们与路由关联。

Filip W 在 customising controller discovery 上写了一篇很好的文章,这让我相信我可以简单地实现 IHttpControllerTypeResolverIAssembliesResolver 来操纵自动发现,使其什么都不做,但是这只解决了一半的问题,而且对于它所解决的一半问题来说,这感觉像是一个糟糕的解决方案——我想有效地禁用发现;但这感觉更像是屠杀发现但保留它......?

一旦发现被禁用,我想通过指定一个控制器(或控制器工厂?)来补偿,这将在服务器初始化之前确定。我可以用 IHttpControllerSelector 处理路由方面,但是我看不出我应该如何指定一个控制器,以便 WebApi 知道它可以工作。

总之我想:

实现此目的最合适的方法是什么(如果有)?

我不受任何特定版本的约束;当前使用 .Net framework 4.7.2 和 Microsoft.AspNet.WebApi.OwinSelfHost 5.2.6.

我认为 HttpControllerSelector 是执行此操作的正确方法。 这是一个小例子:

HttpControllerSelector:

public class HttpControllerSelector : IHttpControllerSelector
{
    private readonly HttpConfiguration _httpConfiguration;

    public HttpControllerSelector(HttpConfiguration httpConfiguration)
    {
        this._httpConfiguration = httpConfiguration;
    }

    public HttpControllerDescriptor SelectController(HttpRequestMessage request)
    {
        return new HttpControllerDescriptor(this._httpConfiguration, 
                                            nameof(ValuesController), 
                                            typeof(ValuesController));
    }

    public IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
    {
        var mapping = new Dictionary<string, HttpControllerDescriptor>
        {
            {
                nameof(ValuesController),
                new HttpControllerDescriptor(this._httpConfiguration,
                                             nameof(ValuesController),
                                             typeof(ValuesController))
            }
        };
        return mapping;
    }
}

WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.Services.Replace(typeof(IHttpControllerSelector), new HttpControllerSelector(config));

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

因此,在 HttpControllerSelector 中,您可以做任何您想做的事情。作为一个简单的例子,有一个总是被选中的控制器。这时候你可以使用工厂或者适合你的东西。

要禁用正常发现,您必须覆盖 WebApiConfig 中显示的正常选择器。

希望这让您知道如何去做,编码愉快!