提问人:Matteo Pietro Peru 提问时间:10/24/2023 最后编辑:Matteo Pietro Peru 更新时间:10/24/2023 访问量:56
仅更改路由中具有继承的 .NET 7 中基控制器类的控制器名称
Change only the controller name in the route having an inherited Base Controller class in .NET 7
问:
我正在实现一个 ASP.NET Core 7 MVC Web 应用程序。
控制器部分由基类管理(该基类实际上具有我将通过在各个操作方法上添加模板来完成的属性),并且其他类从中继承。Route
BaseController
类:
[Route("api/v1/[controller]")]
[ApiController]
public abstract class BaseApiController<TController> : ControllerBase
where TController : ControllerBase
{
// some code
}
继承自 的控制器类的示例:BaseController
public class AuthApiController : BaseApiController<AuthApiController>
{
public AuthApiController(ILogger<AuthApiController> logger, IHttpContextAccessor httpContextAccessor, IUserService? userService)
: base(logger, httpContextAccessor, userService: userService) { }
[HttpGet("new")]
public async Task<IActionResult> CreateNewUser()
{
// some code
}
}
这样,动作的路线是:。CreateNewUser
/api/v1/authapi/new
我的目标是只制作 (),所以我想知道是否有一种或另一种方法可以“合并”基本控制器的路由规则和操作上的各种模板,并且各个控制器的名称也可以自定义。authapi
auth
/api/v1/auth/new
attribute
答:
0赞
Qiang Fu
10/24/2023
#1
您可以覆盖特定操作的路由,不同于控制器使用
尝试以下操作~
[Route("api/v1/[controller]")]
[ApiController]
public class AuthApiController : ControllerBase
{
[HttpGet("new")]
public void test()
{
}
[HttpPost("~/api/v1/auth/new")]
public void test2()
{
}
}
或者也许改变整个控制器的路径使用
[Route("api/v1/auth")]
[ApiController]
评论
0赞
Matteo Pietro Peru
10/24/2023
它当然是这样的,但我想避免在所有操作上重复相同的路线
0赞
Matteo Pietro Peru
10/24/2023
#2
解决
正如这个问题的答案中所建议的,我实现了一个将路由组合在一起的路由,连接两个类的模板:custom attribute
[AttributeUsage(AttributeTargets.Class)]
public class ControllerNestedRouteAttribute : Attribute, IRouteTemplateProvider
{
private readonly Type _controllerType;
public ControllerNestedRouteAttribute(string template, Type controllerType)
{
Name = template;
_controllerType = controllerType;
}
public string Template
{
get
{
// Look up the route from the parent type. This only goes up one level, but if the parent class also has a `NestedRouteAttribute`, then it should work recursively.
Type? baseType = _controllerType.BaseType;
IRouteTemplateProvider? baseTypeRouteAttr = baseType?.GetCustomAttributes().FirstOrDefault(a => a is IRouteTemplateProvider) as IRouteTemplateProvider;
string? baseTypeRouteAttrTemplate = baseTypeRouteAttr?.Template;
if (!string.IsNullOrEmpty(baseTypeRouteAttrTemplate))
{
if (baseTypeRouteAttrTemplate.EndsWith('/'))
return Path.Join(baseTypeRouteAttrTemplate, Name);
else
return Path.Join(baseTypeRouteAttrTemplate, "/", Name);
}
return Name;
}
}
public int? Order => null;
public string Name { get; }
}
在继承的类中:
[ControllerNestedRoute("auth", typeof(AuthApiController))]
public class AuthApiController : BaseApiController<AuthApiController>
{
public AuthApiController(ILogger<AuthApiController> logger, IHttpContextAccessor httpContextAccessor, IUserService? userService)
: base(logger, httpContextAccessor, userService: userService) { }
[HttpGet("new")]
public async Task<IActionResult> CreateNewUser()
{
// some code
}
}
在基本控制器中:
[Route("api/v1")]
[ApiController]
public abstract class BaseApiController<TController> : ControllerBase
where TController : ControllerBase
{
// ...
}
现在我可以使用我想要的路由调用操作。/api/v1/auth/new
评论