我在WebApi 2.0中创建了一个包含所有控制器的控制器程序集,并按照本文 - https://www.strathweb.com/2013/08/customizing-controller-discovery-in-asp-net-web-api/创建了一个CustomAssemblyResolver并添加了代码以替换Application_Start中的程序集解析程序。这是我的代码的样子:
My 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;
}
}
我的Application_Start:
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字符串,这就是我得到的响应:
{ &#34;消息&#34;:&#34;未找到与请求URI匹配的HTTP资源&#39; http://localhost/ExCoWebApi/api/thirdparty/math&#39;。&#34;, &#34; MessageDetail&#34;:&#34;没有找到与名为&#39; Math&#39;。&#39;。&#34;的数字控制器相匹配的类型。 }
调试后我发现AssemblyResolver确实在Application Start中被CustomAssemblyResolver取代,但问题是CustomAssemblyResolver的GetAssemblies()方法没有被调用。因此,包含MathController的程序集无法加载。
我在这里缺少什么?
修改
在拼命寻找解决方案的过程中,我提出了一种测试方法,在其中构建自己的HttpConfiguration对象并替换其中的AssemblyResolver,它就像一个魅力!来自CustomAssemblyResolver的GetAssemblies()函数被调用,我能够调用我的外部控制器。我想知道从&#34; GlobalConfiguration.Configuration&#34返回的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;
}
答案 0 :(得分:1)
发现问题:
没有调用GetAssemblies()的原因是因为为GlobalConfiguration.Configure设置的回调方法(WebApiConfig.Register)正在调用&#34; config.MapHttpAttributeRoutes();&#34;。
GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver),new CustomAssemblyResolver());
代码实际上属于GlobalConfiguration.Configure中配置的回调方法,而不是Global.asax,如果你有为GlobalConfiguration.Configure设置的回调。所以我将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();
}
}