【问题标题】:WebApi 2 AssemblyResolverWeb Api 2 程序集解析器
【发布时间】:2017-09-13 07:07:18
【问题描述】:

我在 WebApi 2.0 中创建了一个包含我所有控制器的控制器程序集,并按照这篇文章 - https://www.strathweb.com/2013/08/customizing-controller-discovery-in-asp-net-web-api/ 创建了一个 CustomAssemblyResolver 并添加了代码来替换 Application_Start 中的程序集解析器。这是我的代码的样子:

我的 CustomAssemblyResolver:

public class CustomAssemblyResolver : DefaultAssembliesResolver
{
    public override ICollection<Assembly> GetAssemblies()
    {
        ICollection<Assembly> baseAssemblies = base.GetAssemblies();
        List<Assembly> assemblies = new List<Assembly>(baseAssemblies);

        string thirdPartySource = "C:\\Research\\ExCoWebApi\\ExternalControllers";

        if (!string.IsNullOrWhiteSpace(thirdPartySource))
        {
            if (Directory.Exists(thirdPartySource))
            {
                foreach (var file in Directory.GetFiles(thirdPartySource, "*.*", SearchOption.AllDirectories))
                {
                    if (Path.GetExtension(file) == ".dll")
                    {
                        var externalAssembly = Assembly.LoadFrom(file);

                        baseAssemblies.Add(externalAssembly);
                    }
                }
            }
        }
        return baseAssemblies;
    }
}

我的应用程序_开始:

    protected void Application_Start()
    {
        Debugger.Launch();

        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());            


    }

如您所见,我正在用 CustomAssemblyResolver 替换默认程序集解析器。

这是我向第三方控制器注册路由的方式:

    public static void RegisterRoutes(RouteCollection routes)
    {            
        routes.MapHttpRoute(
            name: "Test",
            routeTemplate: "api/thirdparty/math",
            defaults: new { controller = "Math" }
        );            
    }

这就是我的 MathController 在单独的程序集中的样子:

public class MathController : ApiController
{
    [HttpPost]
    public int AddValues(MathRequest request)
    {
        int response = MathOperations.Add(request.Value1, request.Value2);
        return response;
    }
}

这是我通过邮递员访问的端点:http://localhost/ExCoWebApi/api/thirdparty/math,在正文中带有 POST 操作和 MathRequest JSON 字符串,这是我得到的响应:

{ "Message": "没有找到与请求 URI 'http://localhost/ExCoWebApi/api/thirdparty/math' 匹配的 HTTP 资源。", "MessageDetail": "没有找到与名为 'Math' 的控制器匹配的类型。" }

调试后,我发现 AssemblyResolver 在应用程序启动时确实被替换为 CustomAssemblyResolver,但问题是 CustomAssemblyResolver 的 GetAssemblies() 方法没有被调用。因此不会加载包含 MathController 的程序集。

我在这里错过了什么??

编辑

为了寻找解决方案,我建立了一个测试方法,在该方法中我构建了自己的 HttpConfiguration 对象并替换了其中的 AssemblyResolver,它就像一个魅力!来自 CustomAssemblyResolver 的 GetAssemblies() 函数被调用,我可以调用我的外部控制器。我想知道从“GlobalConfiguration.Configuration”返回的 HttpConfiguration 对象与手动实例化对象是否有区别。任何帮助对此将不胜感激。这是我的测试方法的代码:

    [TestMethod]
    public void TestExternalControllerCall()
    {
        try
        {
            HttpClient client = GetClient();
            MathRequest mathReq = new MathRequest { Value1 = 10, Value2 = 20 };
            var response = client.PostAsJsonAsync(string.Concat("http://localhost/api/thirdparty/math"), mathReq).Result;
            var entResponse = response.Content.ReadAsAsync<int>().Result;
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
    }

    private HttpClient GetClient()
    {            
        HttpConfiguration config = new HttpConfiguration();
        config.Routes.MapHttpRoute(
            name: "Test",
            routeTemplate: "api/thirdparty/math",
            defaults: new { controller = "Math" }
        );
        config.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());
        HttpServer server = new HttpServer(config);
        HttpClient client = new HttpClient(server);
        return client;        
    }

【问题讨论】:

    标签: c# .net asp.net-web-api


    【解决方案1】:

    发现问题:

    GetAssemblies() 没有被调用的原因是为 GlobalConfiguration.Configure 设置的回调方法 (WebApiConfig.Register) 正在调用“config.MapHttpAttributeRoutes();”。

    GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());

    如果您为 GlobalConfiguration.Configure 设置了回调,则代码实际上属于 GlobalConfiguration.Configure 中配置的回调方法,而不是 Global.asax。所以我把 IAssemblyResolver 替换语句移到了 WebApiConfig 中的 Register 方法中:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());
    
            // Web API routes
            config.MapHttpAttributeRoutes();            
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      • 1970-01-01
      • 2014-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      相关资源
      最近更新 更多