M. *_*har 49 c# asp.net-web-api asp.net-web-api2
我曾经将我的控制器放在Mvc Web Api中的一个单独的类库项目中.我曾经在我的web api项目的global.asax中添加以下行来查找单独项目中的控制器:
ControllerBuilder.Current.DefaultNamespaces.Add("MyClassLibraryProject.Controllers");
Run Code Online (Sandbox Code Playgroud)
除了添加上面的行之外,我从来没有做过任何其他配置.这对我来说一直很好.
但是我无法使用上述方法在WebApi2中执行相同的操作.它只是不起作用.WebApi2项目仍尝试在其自己项目的controllers文件夹中查找控制器.
- 2个月后给予一点摘要更新(因为我开始对此表示赏心悦目):
我创建了一个WebApiOne解决方案,它有2个项目,第一个是WebApi项目,第二个是控制器的类库.如果我将对控制器类库项目的引用添加到WebApi项目中,则所有内容都按预期工作.即如果我去http://mydevdomain.com/api/values我可以看到正确的输出.
我现在创建了一个名为WebApiTwo的第二个项目,它有2个项目,第一个是WebApi2项目,第二个是控制器的类库.如果我将对控制器类库项目的引用添加到WebApi2项目,它将无法按预期工作.即如果我去http://mydevdomain.com/api/values我得到"没有找到匹配名为'值'的控制器的类型."
对于第一个项目,我根本没有做任何自定义设置,我没有:
ControllerBuilder.Current.DefaultNamespaces.Add("MyClassLibraryProject.Controllers");
Run Code Online (Sandbox Code Playgroud)
在我的global.asax中,我没有在他的两篇博文中实现StrathWeb提出的任何自定义解决方案,因为我认为它不再适用; 因为所有工作只是通过将控制器项目的引用添加到WebApi项目.
所以我希望所有人都能为WebApi2工作......但事实并非如此.有没有人真的尝试在WebAPi2中这样做?
Dav*_*idG 29
我刚刚确认这很好用.要检查的事项:
参考:您的主Web API项目是否引用外部类库?
路由:您是否设置了可能干扰外部控制器的路由?
保护级别:外部库中的控制器是public
什么?
继承:外部库中的控制器是否继承ApiController
?
版本控制:您的Web API项目和类库是否都使用相同版本的Web API库?
如果有帮助,我可以打包我的测试解决方案并将其提供给您.此外,作为一个注意事项,您不需要告诉Web API查找带有您添加的行的控制器Global.asax
,系统会自动查找控制器,前提是您已引用它们.
Nik*_*vić 16
它应该按原样运作.清单
ApiController
ValuesController
Clean
解决方案,手动删除bin
文件夹并重建Temporary ASP.NET Files
文件夹.WebApi和MVC缓存控制器查找结果这个控制器:
[RoutePrefix("MyValues")]
public class AbcController : ApiController
{
[HttpGet]
[Route("Get")]
public string Get()
{
return "Ok!";
}
}
Run Code Online (Sandbox Code Playgroud)
匹配此网址:
http://localhost/MyValues/Get
(注意/api/
路线中没有,因为没有在中指定RoutePrefix
.
控制器查找缓存: 这是默认的控制器解析器.您将在源代码中看到它缓存查找结果.
/// <summary>
/// Returns a list of controllers available for the application.
/// </summary>
/// <returns>An <see cref="ICollection{Type}" /> of controllers.</returns>
public override ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver)
{
HttpControllerTypeCacheSerializer serializer = new HttpControllerTypeCacheSerializer();
// First, try reading from the cache on disk
List<Type> matchingTypes = ReadTypesFromCache(TypeCacheName, IsControllerTypePredicate, serializer);
if (matchingTypes != null)
{
return matchingTypes;
}
...
}
Run Code Online (Sandbox Code Playgroud)
遇到了同样的情况,@ justmara让我走上了正确的道路.以下是如何从@ justmara的答案中完成从属程序集的强制加载:
1)重写DefaultAssembliesResolver类
public class MyNewAssembliesResolver : DefaultAssembliesResolver
{
public override ICollection<Assembly> GetAssemblies()
{
ICollection<Assembly> baseAssemblies = base.GetAssemblies();
List<Assembly> assemblies = new List<Assembly>(baseAssemblies);
var controllersAssembly = Assembly.LoadFrom(@"Path_to_Controller_DLL");
baseAssemblies.Add(controllersAssembly);
return baseAssemblies;
}
}
Run Code Online (Sandbox Code Playgroud)
2)在配置部分中,将默认值替换为新实现
config.Services.Replace(typeof(IAssembliesResolver), new MyNewAssembliesResolver());
Run Code Online (Sandbox Code Playgroud)
我使用此博客中的指针拼凑了这个语法:
http://www.strathweb.com/2013/08/customizing-controller-discovery-in-asp-net-web-api/
正如其他人所说,如果您通过直接引用控制器来加载控制器,您就会知道是否遇到了这个问题.另一种方法是示例结果CurrentDomain.GetAssemblies()
并查看您的程序集是否在列表中.
另外:如果您使用OWIN组件进行自托管,您将遇到此问题.测试时请记住,在提交第一个WebAPI请求之前,DefaultAssembliesResolver不会启动(我花了一些时间才意识到这一点).
在调用IAssembliesResolver服务之前,您确定已加载引用的程序集吗?尝试在您的应用程序中插入一些虚拟代码,例如
var a = new MyClassLibraryProject.Controllers.MyClass();
在配置方法(但不要忘记,如果从未使用"a",该编译器可以"优化"此代码并完全删除它.我有与装配加载订单类似的问题.在启动时使用强制加载相关组件结束.
您需要告诉webapi/mvc加载您的referrenced程序集.您可以使用web.config中的compilation/assemblies部分执行此操作.
<compilation debug="true" targetFramework="4.5.2">
<assemblies>
<add assembly="XYZ.SomeAssembly" />
</assemblies>
</compilation>
Run Code Online (Sandbox Code Playgroud)
就那么简单.您可以使用@ user1821052建议的方式使用代码来执行此操作,但此web.config版本将具有相同的效果.
归档时间: |
|
查看次数: |
36443 次 |
最近记录: |