【问题标题】:ASP.Net Web Api Core - Unable to use CreatedAtRoute in abstract base classASP.Net Web Api Core - 无法在抽象基类中使用 CreatedAtRoute
【发布时间】:2017-10-06 16:29:34
【问题描述】:

我的 ASP.Net 核心 Web Api 项目中有一个通用抽象控制器,带有 POST 处理:

 [HttpPost]
 public async Task<IActionResult> Create([FromBody]R itemDto)
 {
     var ret = await _service.CreateNewItemAsync(itemDto);
     return CreatedAtRoute("Get", new { id = ret.Id }, ret);
 }

“获取”路线如下所示:

 [HttpGet("{id}", Name = "Get")]
 public async Task<R> GetAsync(int id)
 {
     var model = await _service.GetItemAsync(id);

     return model;
 }

我有 2 个继承自此基本控制器的控制器类,当我尝试在其中一个控制器上进行简单获取时,我收到以下错误消息:

错误 1: 具有相同名称“Get”的属性路由必须具有相同的模板: 操作:'MyApi.WebApi.Controllers.FooController.GetAsync' - 模板:'api/foo/{id}' 操作:'MyApi.WebApi.Controllers.BarController.GetAsync' - 模板:'api/bar/{id}'

我收到此错误的原因很明显,但我不知道如何在基本控制器中使用命名路由。

谁能指出我正确的方向?

【问题讨论】:

标签: c# asp.net asp.net-web-api .net-core asp.net-core-webapi


【解决方案1】:

使用路由名称参数化BaseController 逻辑。从父级中删除任何路由逻辑。使用const string 参数化子控制器中的属性。然后将此字符串传递给父级:

public class BaseController : Controller
{
    //no routing attributes
    public IActionResult CreateImpl(string routeName)
    {
        //place any logic here
        return CreatedAtRoute(routeName, new object());
    }
}

[Route("api/[controller]")]
public class FooController : BaseController
{
    private const string _getRouteName = "Get_" + nameof(FooController);

    [HttpPost]
    public async Task<IActionResult> Create()
    {
        return CreateImpl(_getRouteName);
    }

    [HttpGet(Name = _getRouteName)]
    public override string Get()
    {
        return base.Get();
    }
}

【讨论】:

  • 感谢您的回答。在您的代码中,您将 Get 和 Post 放在派生类中。我的代码在 BaseController 中包含所有逻辑,因为为了避免代码重复。是否有机会避免在每个派生控制器中使用相同的代码?
  • 好吧,我读你的代码太快了。据我了解asp.net核心中的路由,我没有其他机会这样做。
  • @ThomasGeulen,没错,Get 和 Post 不包含任何业务逻辑。子控制器仅管理路由。由于我们不能声明多个同名路由,因此子控制器应该声明自己的路由。
【解决方案2】:

使用CreatedAtAction 而不是CreateAtRoute,它仍然会返回状态201,您无需担心路由名称。感谢@CodeFuller 这就是我解决同样问题的方法。

 return CreatedAtAction(nameof(GetAsync), new { id = 123 }, createObjectDto);

请参考以下链接Route Name for HttpGet attribute Name for base generic controller class in asp.net core

【讨论】:

    猜你喜欢
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 2016-08-02
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 2022-08-07
    • 2018-08-25
    相关资源
    最近更新 更多