【问题标题】:Web Api Optional Parameters in the middle with attribute routing中间带属性路由的Web Api Optional Parameters
【发布时间】:2016-08-02 19:53:43
【问题描述】:

所以我正在使用Postman 测试我的一些路由,但我似乎无法让这个电话通过:

API函数

[RoutePrefix("api/Employees")]
public class CallsController : ApiController
{
    [HttpGet]
    [Route("{id:int?}/Calls/{callId:int?}")]
    public async Task<ApiResponse<object>> GetCall(int? id = null, int? callId = null)
    {
        var testRetrieve = id;
        var testRetrieve2 = callId;

        throw new NotImplementedException();
    }
}

邮递员请求

http://localhost:61941/api/Employees/Calls 不起作用

错误:

{
  "Message": "No HTTP resource was found that matches the request URI 'http://localhost:61941/api/Employees/Calls'.",
  "MessageDetail": "No action was found on the controller 'Employees' that matches the request."
}

http://localhost:61941/api/Employees/1/Calls 工作

http://localhost:61941/api/Employees/1/Calls/1 工作

知道为什么我不能在前缀和自定义路由之间使用可选项吗?我尝试将它们组合成一个自定义路由,这并没有改变任何东西,任何时候我尝试删除 id 都会导致问题。

【问题讨论】:

    标签: c# asp.net asp.net-web-api asp.net-mvc-routing


    【解决方案1】:

    可选参数必须在路由模板的末尾。所以你想要做的事情是不可能的。

    Attribute routing: Optional URI Parameters and Default Values

    你要么改变你的路线模板

    [Route("Calls/{id:int?}/{callId:int?}")]
    

    或创建一个新动作

    [RoutePrefix("api/Employees")]
    public class CallsController : ApiController {
    
        //GET api/Employees/1/Calls
        //GET api/Employees/1/Calls/1
        [HttpGet]
        [Route("{id:int}/Calls/{callId:int?}")]
        public async Task<ApiResponse<object>> GetCall(int id, int? callId = null) {
            var testRetrieve = id;
            var testRetrieve2 = callId;
    
            throw new NotImplementedException();
        }
    
        //GET api/Employees/Calls
        [HttpGet]
        [Route("Calls")]
        public async Task<ApiResponse<object>> GetAllCalls() {
            throw new NotImplementedException();
        }
    }
    

    【讨论】:

    • 我今天的选票已用完。 :D #SOReadyToHelp。
    • 遗憾的是,为了使 .NET 功能正常工作,我们需要做出改变——即使它们看起来不合逻辑。希望MS将来能改进他们的属性功能......
    【解决方案2】:

    我会将路线更改为:

    [Route("Calls/{id:int?}/{callId:int?}")]
    

    并将[FromUri] 属性添加到您的参数中:

    ([FromUri]int? id = null, [FromUri]int? callId = null)
    

    我的测试函数如下所示:

    [HttpGet]
    [Route("Calls/{id:int?}/{callId:int?}")]
    public async Task<IHttpActionResult> GetCall([FromUri]int? id = null, [FromUri]int? callId = null)
    {
        var test = string.Format("id: {0} callid: {1}", id, callId);
    
        return Ok(test);
    }
    

    我可以使用:

    https://localhost/WebApplication1/api/Employees/Calls
    https://localhost/WebApplication1/api/Employees/Calls?id=3
    https://localhost/WebApplication1/api/Employees/Calls?callid=2
    https://localhost/WebApplication1/api/Employees/Calls?id=3&callid=2
    

    【讨论】:

      【解决方案3】:

      其实你不需要在路由中指定可选参数

      [Route("Calls")]
      

      或者你需要改变路线

       [Route("Calls/{id:int?}/{callId:int?}")]
       public async Task<ApiResponse<object>> GetCall(int? id = null, int? callId = null)
      

      【讨论】:

      • 虽然它作为一个单独的函数工作,但我希望将所有 3 个潜在调用封装在 1 个函数下,如果我理解可选路由正确,它应该是可能的。
      猜你喜欢
      • 2017-03-24
      • 2015-06-21
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多