如何解决从类库注册Web API控制器 解决问题您不需要的东西
我有一个.NET Core worker项目,并且想要添加一个提供几个HTTP端点的库。 我必须留在worker项目中,不能将其更改为Web API项目。到目前为止,我已经做过的事情:
- 我创建了一个工人项目
- 我创建了一个图书馆项目
- 我在worker项目中添加了对库的引用
- 在 Worker.csproj 和 Lib.csproj 中,我向项目组添加了
<FrameworkReference Include="Microsoft.AspNetCore.App" />
,以访问webbuilder的内容 - 我在库项目中安装了软件包 Microsoft.AspNetCore.Mvc.Core
- 在图书馆项目中,我添加了几个扩展类和一个用于测试目的的Web API控制器
。
public static class IApplicationBuilderExtensions
{
public static IApplicationBuilder AddLibrary(this IApplicationBuilder applicationBuilder)
{
applicationBuilder.UseRouting();
applicationBuilder.UseEndpoints(endpoints => { endpoints.MapControllers(); });
return applicationBuilder;
}
}
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddLibrary(this IServiceCollection services)
{
services.AddMvc(); // this might be not needed
services.AddControllers();
return services;
}
}
public static class KestrelServerOptionsExtensions
{
public static void AddLibrary(this KestrelServerOptions kestrelServerOptions)
{
kestrelServerOptions.ListenLocalhost(5000); // value from config
}
}
[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
[HttpGet]
public async Task<ActionResult> Test()
{
return Ok();
}
}
- 在工作人员项目中,我创建了一个
Startup
类
。
internal class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddLibrary();
}
public void Configure(IApplicationBuilder applicationBuilder)
{
applicationBuilder.AddLibrary();
}
}
- 在工作人员项目中,我将
Program
类修改为
。
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webHostBuilder =>
{
webHostBuilder.UseKestrel(kestrelServerOptions =>
{
kestrelServerOptions.AddLibrary();
}).UseStartup<Startup>();
})
.ConfigureServices((hostContext,services) =>
{
services.AddHostedService<Worker>();
});
}
- 我运行项目并调用 GET http:// localhost:5000 / users
- 我期望200,但得到404,调试器不会访问库项目中的控制器端点
有人知道我想念什么吗?
我可以Add Web API controller endpoint to Kestrel worker project,但不能将Web控制器添加到库项目并从库中调用它们。
解决方法
我的计算机上有可行的解决方案。
解决问题
事实证明,这实际上非常简单。 MVC从不同的程序集中加载ApplicationPart
。在正常的Web应用程序设置中,即使使用Razor类库,也似乎可以正确地拾取它。但是,当使用辅助服务和库或Razor类库时,它不起作用,因此不会注册控制器的路由。
要将库添加为应用程序部分,请打开您创建的IServiceCollectionExtensions
类,并将其更改为:
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddLibrary(this IServiceCollection services)
{
services
.AddControllers()
// Notice the assembly is the type of this class,as this
// is the assembly the controller is in.
// You'll have to call this for every assembly you have
// controllers in,except for any controllers
// you might put in your worker service project.
.AddApplicationPart(typeof(IServiceCollectionExtensions).Assembly);
return services;
}
}
现在,启动应用程序并向http://localhost:5000/users
发送请求即可。我已经确认该功能适用于库和Razor类库。
我还应该说,工作者服务项目中的控制器将正常运行-不需要特殊的设置。
您不需要的东西
- 您不需要在
services.AddMvc()
中呼叫IServiceCollectionExtensions
。无需参数即可调用的是same as callingAddControllersWithViews()
andAddRazorPages()
。 - 您在库项目中不需要
Microsoft.AspNetCore.Mvc.Core
软件包-我添加的框架引用可以很好地运行我的软件包。我唯一的包裹是Microsoft.AspNetCore.Server.Kestrel.Core
。
首先,您的问题看上去与所引用的问题相同,唯一的区别是该问题。所以您没有说为什么您的Web控制器不起作用,您遇到了什么错误?
然后,您没有说要使用哪个ASP.NET Core版本?这很重要,因为2.x和3.x是不同的东西。
因此,请更新您的问题以澄清这些问题。同时,我确实尝试了您的代码,这就是我发布此答案的原因。
我正在使用.NET Core 5 RC,并且Web控制器对我有用。我唯一要处理的就是编译Razor视图,因为Sdk.Worker
默认情况下不编译视图。按下控制器时,出现500错误,提示即使视图位于正确的位置也找不到视图。然后,我使用了Razor runtime compilation,一切都开始对我起作用。
这就是我所拥有的:
Program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webHost =>
{
webHost.UseKestrel(opt =>
{
opt.ListenLocalhost(5000);
});
webHost.UseStartup<Startup>();
})
.ConfigureServices((hostContext,services) =>
{
services.AddHostedService<Worker>();
});
Startup.cs
class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews().AddRazorRuntimeCompilation();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "MyArea",pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(
name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
TestController.cs
[Area("My")]
[Route("users")]
public class TestController : Controller
{
[Route("")]
public IActionResult Index()
{
return View();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。