HttpGet属性的路由名称asp.net core 2中基本通用控制器类的名称

我有一个通用控制器,它有几个派生的控制器类。 但我无法弄清楚如何处理HttpGet的路由名称,因为它需要不变。

[HttpGet("{id}", Name ="should not hard coded here for derived class")] public virtual async Task Get(int id) 

我需要路由名称,因为在我的HttpPost函数中我想返回需要HttpGet 路由名称的 CreatedAtRoute()

路径名称不能进行硬编码,因为所有派生类都需要具有不同的路由名称。

这是基本控制器

 public abstract class BaseController : Controller where TEntity : BaseOptionType, new() where TContext : DbContext { private readonly IGenericRepository _repository; private readonly ILogger<BaseGenericOptionTypesController> _logger; public BaseController(IGenericRepository repository, ILogger<BaseController> logger) { _repository = repository; _logger = logger; } [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [HttpGet("{id}", Name = "should not hard code here for derived class")] public virtual async Task Get(int id) { var optionType = await _repository.FindByIdAsync(id); if (optionType == null) { _logger.LogInformation($"[ID not found]"); return NotFound(); } return Ok(optionType); } } 

这是派生控制器

 [Route("api/v1/DerivedControllerA")] public class DerivedControllerA : BaseController { public DerivedControllerA(IGenericRepository repository, ILogger logger) : base(repository, logger) { } } 

任何帮助将不胜感激,谢谢。

我不会与NightOwl888争论在MVC中使用基本控制器。 有利有弊,我已经处理过使用基本控制器的项目是合理的。

至于原始问题,似乎解决这个问题的最简单方法是使用CreatedAtAction而不是CreatedAtRouteCreatedAtAction不要求您为路由命名,您只需使用从基本控制器Get操作名称即可。 如果从DerivedControllerA调用DerivedControllerA ,它将在DerivedControllerA生成Get动作的URL,如果从DerivedControllerB调用它,它将在DerivedControllerB生成Get动作的URL。 所以转向CreatedAtAction似乎CreatedAtAction涵盖了你的用例。

以下是对CreatedAtAction的示例调用:

 [HttpPost] public virtual IActionResult Post(/* ... */) { // Create and save an instance in repository // var createdObject = ...; return CreatedAtAction(nameof(Get), new { // Put actual id here id = 123 }, createdObject); } 

常见的错误是使用2个参数调用CreatedAtAction重载。 此版本为响应正文创建了对象,而不是路由值,这通常会导致No route matches the supplied values错误No route matches the supplied values 。 如果您不想在响应中返回已创建资源的表示,则可以将null作为第3个参数传递:

  return CreatedAtAction(nameof(Get), new { // Put actual id here id = 123 }, null); 

如果由于某种原因你想坚持使用CreatedAtRoute调用,我想到的唯一可能的解决方案是在每个派生类中使用不同的操作,它只使用实际逻辑调用base方法:

 [Route("api/v1/DerivedControllerA")] public class DerivedControllerA : BaseController { // ... [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [HttpGet("{id}", Name = "RouteForDerivedControllerA")] public virtual Task Get(int id) { return base.Get(id); } } public abstract class BaseController : Controller where TEntity : BaseOptionType, new() where TContext : DbContext { // ... public virtual async Task Get(int id) { // Actual logic goes here } } 

然而,这样的解决方案实际上使BaseController使用贬值。