如何使用相似但不同的参数创建 ASP.NET Core Web API 控制器方法

How to create ASP.NET Core Web API controller method with similar but different parameter

我用 ASP.NET 核心创建了一个简单的 Web API。我有以下 API:

现在,我想要另一个 API 按消息所有者的姓名获取所有消息。

我试过的:

我试图创建这个 API,但它不起作用,因为它与 GET /api/messages/{id}:

冲突

这是我的消息模型Message.cs:

public class Message
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }
    public string Owner { get; set; }
    public string Text { get; set; }
}

这是我的消息控制器MessagesController.cs

[Route("api/[controller]")]
public class MessagesController : Controller
{
    private readonly IMessageRepository _repository;

    public MessagesController(IMessageRepository repository)
    {
        _repository = repository;
    }

    // GET: api/messages
    [HttpGet]
    public IEnumerable<Message> Get()
    {
        return _repository.GetMessages();
    }

    // GET api/messages/{id}
    [HttpGet("{id}", Name = "GetMessage")]
    public IActionResult GetById(long id)
    {
        var message = _repository.GetMessage(id);
        if (message == null)
        {
            return NotFound();
        }
        return new ObjectResult(message);
    }

    // POST api/messages
    [HttpPost]
    public IActionResult Post([FromBody]Message message)
    {
        if (message == null)
        {
            return BadRequest();
        }

        _repository.AddMessage(message);

        return CreatedAtRoute("GetMessage", new { id = message.Id }, message);

    }

    // PUT api/messages/{id}
    [HttpPut("{id}")]
    public IActionResult Put(long id, [FromBody]Message message)
    {
        if (message == null || message.Id != id)
        {
            return BadRequest();
        }

        var messageToUpdate = _repository.GetMessage(id);
        if (messageToUpdate == null)
        {
            return NotFound();
        }

        messageToUpdate.Owner = message.Owner;
        messageToUpdate.Text = message.Text;

        _repository.UpdateMessage(messageToUpdate);
        return new NoContentResult();
    }

    // DELETE api/messages/{id}
    [HttpDelete("{id}")]
    public IActionResult Delete(long id)
    {
        var message = _repository.GetMessage(id);
        if (message == null)
        {
            return NotFound();
        }
        _repository.RemoveMessage(id);
        return new NoContentResult();
    }
}

问题:

如何创建一个 API 方法来通过邮件所有者的姓名获取所有邮件?

理想情况下,我希望 API 看起来像 GET /api/messages/{name},但认为这不可能,因为它与 GET /api/messages/{id} 冲突}.

我正在考虑像这样创建 API,但我不确定如何创建。

解决方案:

要让 GET /api/messages/{name} 工作而不与 GET /api/messages/{id} 发生冲突,请将 [=17= 的属性 [HttpGet("{id}", Name="GetMessage")] 更改为 [HttpGet("{id:long}", Name="GetMessage")] ]方法。

要让 GET /api/messages/name/{name} 正常工作,请将 [Route("name/{name}")] 属性添加到 public IEnumerable<Message> GetMessagesByName(string name) 方法。

你可以把参数类型放在路由中,所以你的代码方法应该是这样的:

 // GET api/messages/{id}
    [HttpGet("{id:long}", Name = "GetMessage")]
    public IActionResult GetById(long id)
    {
        var message = _repository.GetMessage(id);
        if (message == null)
        {
            return NotFound();
        }
        return new ObjectResult(message);
    }

我认为,web api 会忽略路由中的参数类型,如果它们没有显式输入的话,所以在你的例子中它有两条这样的路由:api/messages/{object} 并且当你输入显式类型时,他们是这样的:api/messages/{object}api/messages/{long}