SelfHosted AspNet WebAPI 与不同项目中的控制器类

Posted

技术标签:

【中文标题】SelfHosted AspNet WebAPI 与不同项目中的控制器类【英文标题】:SelfHosted AspNet WebAPI With Controller Classes In Different Project 【发布时间】:2013-06-18 01:53:50 【问题描述】:

我使用 Visual Studio 2012 (.NET Framework 4.5) 创建了一个 SelfHosted AspNet WebAPI。我为 WebAPI 启用了 SSL。当控制器在同一个项目中定义时,它可以正常工作。

但是当我添加另一个项目的引用时,包含控制器,它给了我以下错误:

未找到与请求 URI 'https://xxx.xxx.xxx.xxx:xxxx/hellowebapi/tests/'匹配的 HTTP 资源。

我已经为 HttpSelfHostConfiguration 和 MessageHandler 创建了自定义类。

对解决这个问题的任何帮助对我来说都是一种很好的消磨时间。

提前致谢。

【问题讨论】:

【参考方案1】:

您可以编写一个简单的自定义程序集解析器,以确保加载您引用的程序集以供控制器探测工作。

以下是 Filip 关于此的一篇不错的帖子:http://www.strathweb.com/2012/06/using-controllers-from-an-external-assembly-in-asp-net-web-api/

示例:

class Program

    static HttpSelfHostServer CreateHost(string address)
    
        // Create normal config
        HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(address);

        // Set our own assembly resolver where we add the assemblies we need
        CustomAssembliesResolver assemblyResolver = new CustomAssembliesResolver();
        config.Services.Replace(typeof(IAssembliesResolver), assemblyResolver);

        // Add a route
        config.Routes.MapHttpRoute(
          name: "default",
          routeTemplate: "api/controller/id",
          defaults: new  controller = "Home", id = RouteParameter.Optional );

        HttpSelfHostServer server = new HttpSelfHostServer(config);
        server.OpenAsync().Wait();

        Console.WriteLine("Listening on " + address);
        return server;
    

    static void Main(string[] args)
    
        // Create and open our host
        HttpSelfHostServer server = CreateHost("http://localhost:8080");

        Console.WriteLine("Hit ENTER to exit...");
        Console.ReadLine();
    


public class CustomAssembliesResolver : DefaultAssembliesResolver

    public override ICollection<Assembly> GetAssemblies()
    
        ICollection<Assembly> baseAssemblies = base.GetAssemblies();

        List<Assembly> assemblies = new List<Assembly>(baseAssemblies);

        var controllersAssembly = Assembly.LoadFrom(@"C:\libs\controllers\ControllersLibrary.dll");

        baseAssemblies.Add(controllersAssembly);

        return assemblies;
    

【讨论】:

这不是必须的。默认解析器从当前 appdomain 获取所有程序集。我一直在其他组件中使用控制器,并且它大部分时间都在工作。我不得不承认我遇到过它似乎不起作用的情况,但我从来没有弄清楚为什么。 @DarrelMiller:这取决于您是否在另一个程序集中引用了导致程序集加载的类型,在这种情况下,探测将起作用。例如,在上面的示例中,如果不使用程序集解析器,我可以执行Type valuesControllerType = typeof(ControllersLibrary.ValuesController); 之类的操作,这将导致程序集被加载。 啊,谢谢你的洞察力。我通常在带有控制器的 DLL 中有一个 MyApi.Configure(config) 方法,这样可以保证程序集被加载。 @DarrelMiller:我观察到,如果您正在使用 MVC 项目,那么在另一个程序集中拥有控制器是没有问题的。但是,每当您尝试自托管您的 webapi 时,即使它具有项目引用,自托管也不会加载其他程序集。在这种特殊情况下,您必须编写自己的程序集解析器。 @ImranNazir:你可以先看看我的评论。只要您可以加载程序集,即使在 selfhost 的情况下也不必拥有程序集解析器。

以上是关于SelfHosted AspNet WebAPI 与不同项目中的控制器类的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft.AspNet.WebApi.OData 与 Microsoft.Data.OData 和 Microsoft.AspNet.OData 有啥区别?

Microsoft.AspNet.WebApi.Core 和过时的库

Microsoft.Net.Http 与 Microsoft.AspNet.WebApi.Client

将数据发布到 WebApi 时,DataTables.AspNet IDataTablesRequest 为空

AspNet WebApi: 了解下HttpControllerDispatcher,控制器的创建和执行

ASPNET_WEBAPI快速学习02