【问题标题】:REST API signature of functions函数的 REST API 签名
【发布时间】:2019-01-17 02:21:15
【问题描述】:

我想在浏览器 /api/announce 和 /api/announce/1 中调用。 使用以下 Get 函数出现错误。当我注释掉其中一个或其他作品时,但如果我同时拥有这两个功能,则 GET 无法按预期工作。是签名有问题还是有其他问题?

   /api/announce
   [HttpGet]
    public List<Announcement> GetAnnouncements()
    {

        Services.Interface.IAnnouncementService service = new Services.Imp.AnnouncementService(_configuration, _logger);

        Announcements announcements = service.GetAnnouncements(1, 1);
        return announcements;

    }

    /api/announce/1
    [HttpGet]
    public ActionResult<Announcement> GetAnnouncements([FromQuery]int ID)
    {

        Services.Interface.IAnnouncementService service = new Services.Imp.AnnouncementService(_configuration, _logger);

        Announcement announcement = service.GetAnnouncement(ID);
        return announcement;

    }

【问题讨论】:

  • 尝试将参数命名为id,而不是ID
  • 并且“评论”将其显示为路径参数
  • 究竟是什么错误?

标签: c# .net rest asp.net-web-api


【解决方案1】:

你的路由规则的签名是一样的,所以会抛出这个异常:Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException: Multiple actions matched.

要让框架了解您要调用的操作,您必须更具体地了解路由。而如果你想将参数作为路径的一部分传递,你必须将[FromQuery]属性更改为[FromRoute]属性。

例子:

  [HttpGet]
  public IActionResult Test()
  {
    return Ok();
  }

  [HttpGet("{id}")]
  public IActionResult Test([FromRoute]int id)
  {
    return Ok();
  }

【讨论】:

    【解决方案2】:

    这就是我喜欢的方式:

        [HttpGet]
        [ProducesResponseType(typeof(IList<Currency>), 200)]
        public async Task<IActionResult> GetAll()
        {
            return Ok(await _typeService.GetCurrenciesAsync().ConfigureAwait(false));
        }
    
        [HttpGet("{id}", Name = "GetCurrency")]
        [ProducesResponseType(typeof(Currency), 200)]
        public async Task<IActionResult> Get([FromRoute]int id)
        {
            return Ok(await _expenseService.GetCurrencyAsync(id).ConfigureAwait(false));
        }
    

    我们可以大摇大摆地看到这样的东西:

    /api/Currency
    /api/Currency/{id}
    

    您的基本控制器可能是这样的,以包含基本路由:

    [Authorize(Policy = Common.Security.Policies.ApiUser)]
    [Route("api/[controller]")]
    [Benchmark, ApiController]
    public abstract class BaseController : ControllerBase
    {
        protected BaseController()
        { }
    }
    

    为了完整性,这里是控制器构造函数:

    public class CurrencyController : BaseController
    {
        private readonly IExpenseEntryService _expenseService;
        private readonly ITypeService _typeService;
    
        public CurrencyController(ITypeService typeService, IExpenseEntryService expenseService)
        {
            _expenseService = expenseService;
            _typeService = typeService;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      相关资源
      最近更新 更多