从 class 库注册 Web API 控制器
register Web API controller from class library
我有一个 .NET Core 工作项目,想要添加一个提供多个 HTTP 端点的库。 我必须留在 worker 项目中,我无法将其更改为 Web API 项目。 目前我所做的:
- 我创建了一个工人项目
- 我创建了一个库项目
- 我在工作项目中添加了对库的引用
- 在Worker.csproj和Lib.csproj中我添加了
<FrameworkReference Include="Microsoft.AspNetCore.App" />
到项目组获得网站建设者的东西
- 我在库项目
中安装了包Microsoft.AspNetCore.Mvc.Core
- 在库项目中,我添加了几个扩展 classes 和一个网络 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();
}
}
- 在worker项目中我创建了一个
Startup
class
.
internal class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddLibrary();
}
public void Configure(IApplicationBuilder applicationBuilder)
{
applicationBuilder.AddLibrary();
}
}
- 在worker项目中我将
Program
class修改为
.
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,并且调试器没有命中库项目中的控制器端点
有人知道我错过了什么吗?
我可以 但我无法将 Web 控制器添加到库项目并从库中调用它们。
我的电脑上有一个可行的解决方案。
解决问题
事实证明其实很简单。 MVC 从不同的程序集加载 ApplicationPart
s。在正常的 Web 应用程序设置中,即使使用 Razor Class 库,这似乎也能正确获取。但是,当使用辅助服务和库或 Razor Class 库时,它不起作用,因此您的控制器的路由未注册。
要将库添加为应用程序部分,请打开您创建的 IServiceCollectionExtensions
class,并将其更改为:
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 Class 库。
我还应该说,worker 服务项目中的控制器本身将正常工作——这些控制器不需要特殊设置。
你不需要的东西
- 您不需要在
IServiceCollectionExtensions
中调用 services.AddMvc()
。不带参数的调用是 same as calling AddControllersWithViews()
and AddRazorPages()
.
- 您的库项目中不需要
Microsoft.AspNetCore.Mvc.Core
包 - 我的仅使用您添加的框架引用即可正常运行。我那里唯一的包裹是 Microsoft.AspNetCore.Server.Kestrel.Core
.
我有一个 .NET Core 工作项目,想要添加一个提供多个 HTTP 端点的库。 我必须留在 worker 项目中,我无法将其更改为 Web API 项目。 目前我所做的:
- 我创建了一个工人项目
- 我创建了一个库项目
- 我在工作项目中添加了对库的引用
- 在Worker.csproj和Lib.csproj中我添加了
<FrameworkReference Include="Microsoft.AspNetCore.App" />
到项目组获得网站建设者的东西 - 我在库项目 中安装了包Microsoft.AspNetCore.Mvc.Core
- 在库项目中,我添加了几个扩展 classes 和一个网络 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();
}
}
- 在worker项目中我创建了一个
Startup
class
.
internal class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddLibrary();
}
public void Configure(IApplicationBuilder applicationBuilder)
{
applicationBuilder.AddLibrary();
}
}
- 在worker项目中我将
Program
class修改为
.
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,并且调试器没有命中库项目中的控制器端点
有人知道我错过了什么吗?
我可以
我的电脑上有一个可行的解决方案。
解决问题
事实证明其实很简单。 MVC 从不同的程序集加载 ApplicationPart
s。在正常的 Web 应用程序设置中,即使使用 Razor Class 库,这似乎也能正确获取。但是,当使用辅助服务和库或 Razor Class 库时,它不起作用,因此您的控制器的路由未注册。
要将库添加为应用程序部分,请打开您创建的 IServiceCollectionExtensions
class,并将其更改为:
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 Class 库。
我还应该说,worker 服务项目中的控制器本身将正常工作——这些控制器不需要特殊设置。
你不需要的东西
- 您不需要在
IServiceCollectionExtensions
中调用services.AddMvc()
。不带参数的调用是 same as callingAddControllersWithViews()
andAddRazorPages()
. - 您的库项目中不需要
Microsoft.AspNetCore.Mvc.Core
包 - 我的仅使用您添加的框架引用即可正常运行。我那里唯一的包裹是Microsoft.AspNetCore.Server.Kestrel.Core
.