asp.net-core - ASP NET Core 在类中定义 API 控制器
问题描述
我目前正在从 .net 框架切换到 .net core 3.1。
在命名空间内定义 Api 控制器一切正常且有效。
现在我有一个案例,我需要在另一个类中声明 Api 控制器,如下所示:
namespace Api.Controllers
{
public class MainClass : BaseClass
{
public MainClass()
{
}
[ApiController]
[Route("Test")]
public class TestController : ControllerBase
{
[HttpGet]
public int GetResult()
{
return 0;
}
}
}
}
结果是,在启动类的“ConfigureServices”方法中调用“AddControllers”方法后找不到Api Controller。
MainClass 在调用 Startup 类之前被实例化。
我尝试更改全局路由并定义类似“{area=Test}/{controller=Test}”的区域,或者在 MainClass 上方设置 ApiController 属性,但它们都不起作用。
有没有办法让这个工作?
解决方案
看起来默认ControllerFeatureProvider
不将嵌套控制器类型视为控制器。您可以添加(不需要替换)您的自定义提供程序来更改该行为,如下所示:
public class NestedControllerFeatureProvider : ControllerFeatureProvider
{
protected override bool IsController(TypeInfo typeInfo)
{
if(!typeInfo.IsClass) return false;
if(typeInfo.IsAbstract) return false;
var isNestedType = typeInfo.DeclaringType != null;
var isPublic = true;
var parentType = typeInfo.DeclaringType;
while(parentType != null){
isPublic = parentType.IsPublic;
parentType = parentType.DeclaringType;
}
return isNestedType && isPublic;
}
}
然后将该提供程序添加到ApplicationPartManager
in 中,Startup.ConfigureServices
如下所示:
services
.AddMvc()
.ConfigureApplicationPartManager(appPart => {
appPart.FeatureProviders.Add(new NestedControllerFeatureProvider());
});
如果要替换默认值ControllerFeatureProvider
,只需在 中找到FeatureProviders
并删除即可。当然,您需要确保您的自定义项应该像默认逻辑一样处理所有内容,如下所示:
//for IsController
return base.IsController(typeInfo) || <...your-custom-logic...>;
注意:您可以参考ControllerFeatureProvider的默认实现来学习一些标准逻辑来正确实现自己的逻辑。上面的代码只是一个基本示例。对我来说,只要类继承自ControllerBase
而不是abstract
,它们就可以作为控制器正常工作以服务请求。除了一些奇怪的约定(例如:不以结尾的类名Controller
仍然是控制器或应用于控制器类的某些标准属性不起作用......)之外,不会有严重的麻烦。
我们不应该使用嵌套的控制器类。每个控制器类都应该放在一个单独的文件中(作为一个好习惯)。然而这个答案的重点(我很确定不是很多人知道的最有趣的部分是使用ControllerFeatureProvider
它可以帮助您自定义其他场景中设置的功能)。真的,如果你真的必须以某种方式坚持你的设计,你当然必须使用这个解决方案,别无他法。
推荐阅读
- c - 构建 git-credential-libsecret 时遇到问题:未知类型名称“SecretService”
- sql - 如何在特定时间获取数据库上的事务
- wordpress - AWS S3 RSS 源
- typescript - 单元测试:TypeError:无法读取未定义的属性“管道”
- python-3.x - 将加权列表添加在一起
- java - 无法模拟 ReactriveJWTDecoder
- angular - 动态导航栏和 Angular 4 路由
- spring-boot - 使用ansible自动更新spring boot docker app
- unit-testing - Nestjs中的单元测试ClientProxy
- database - Azure 中具有快速更新选项的超大型数据集的最佳存储