【问题标题】:.Net Core API - Route Parameters in Query String not working.Net Core API - 查询字符串中的路由参数不起作用
【发布时间】:2023-01-27 13:16:47
【问题描述】:

我们正在将 Web API 升级到 .Net Core。该 API 是一个 Employees API,具有 Employee Search 和 GET 端点,如下所示:

GET /employees/{id}
GET /employees

对于 Get 端点,目前以下两个调用都有效:

https://example.com/employees/001
https://example.com/employees/{id}?id=001

将代码升级到 .Net Core 6.0 后,只有以下调用有效:

https://example.com/employees/001

查询字符串中带有 id 的另一个调用不起作用。有没有办法让这两个调用在 .Net Core 中工作

【问题讨论】:

    标签: .net api rest asp.net-core asp.net-core-webapi


    【解决方案1】:

    这就是您定义路线的方式。如果将参数放在路由中,例如 /employees/001,它将查找该路径以确定要命中的函数。因此,例如我设置了 2 个调用 2 个函数的路由:

        [Route("Stuff/{id}")]
        public IActionResult StuffWithIDInPath(int id)
        {
            ViewData["idVal"] = id;
            return View("SomeStuff");
        }
    
        [Route("Stuff")]
        public IActionResult StuffWithIDInQS(int id)
        {
            ViewData["idVal"] = id;
            return View("SomeStuff");
        }
    

    当我去 something/stuff/37 时,第一条路线被击中

    而第二个函数在路由中没有参数,但它也是函数的参数,所以它知道如果出现就去寻找它:

    但也许您想要一个函数来处理这两种情况,如果您只是为同一函数正确定义路由,则可以同时处理这两种情况。

        [Route("Stuff/{id}")]
        [Route("Stuff")]
        public IActionResult StuffWithIDEitherPlace(int id)
        {
            ViewData["idVal"] = id;
            return View("SomeStuff");
        }
    

    在这种情况下,任一 URL 都将转到该函数,处理路由中的参数或作为查询字符串。

    【讨论】:

    • 这不起作用,因为我们已经有一个具有相同路由的搜索端点
    • 你想使用什么路线?你想如何传递参数?也许用那个更新问题会有所帮助。
    • 我需要使用 Get By Id Route -> /employees/{id} 应该同时接受 example.com/employees/001, example.com/employees{id}?id=001 这曾经在 .Net Framework 代码中工作。
    • 你说 example.com/employees 路由已经被“占用”了吗?我不确定之前完整的框架是如何工作的,坦率地说,它不应该允许两条路由通过一条路由过滤,但是如果某些东西已经在使用该 URL,则您不能再次使用它。
    • @SillyJohn 我也遇到了和你一样的问题,根据我的研究,你是对的,回到 .NET 4 中它确实有效,但现在它在 .NET Core 中不起作用,所以我也在寻找解决方法.如果你找到我做的一个 b4,请分享! TX
    【解决方案2】:

    你的动作路由属性应该有 id 作为可选参数

         [HttpGet("~/employees/{id?}")]
        public IActionResult Get(int? id)
    

    或者如果控制器是员工

     public class Employees : ApiController
    ..........
        [HttpGet("id?}")]
        public IActionResult Get(int? id)
    

    【讨论】:

    • 这似乎不起作用。我正在使用 .Net Core 6.0 框架。我收到错误 - {"type":"tools.ietf.org/html/… or more validation errors occurred.","status":400,"traceId":"00-62dd6653938ff33fa3f6a5a35f09e1b4-5fe2142d49d4773d-00","errors":{"id ":["值 '{id}' 无效。"]}}
    • @SillyJohn 你能展示你的完整网址吗?
    • 我尝试了以下 3 - localhost:5271/WeatherForecast/4 -> 这有效; localhost:5271/employees/id?id=4 -> 这不起作用; localhost:5271/employees/%7Bid%7D?id=4 -> 这不起作用;
    • @SillyJohn 您也可以使用 localhost:5271/WeatherForecast?id=4 。 localhost:5271/employees/id?id=4 没有任何意义,localhost:5271/employees/%7Bid%7D?id=4 也没有任何意义。
    • Ya only localhost:5271/WeatherForecast/4 是有道理的。但问题是,这三个都曾经在 .Net Framework 中工作,我们实际上正在从 .Net Framework 升级到 .Net Core 6.0,这对消费者来说将是一个突破性的变化。只是在想是否有解决方法
    【解决方案3】:

    当我最终像这样合并我的 .NET Framework Get() & Get(string lat, string lng) 时,这起作用了。如果我是从头开始创建它,我不会这样做,但我有一个 IOS 应用程序需要在我将我的 API 迁移到 .NET Core 后进行更新。

    // Get All Restaurants OR Get By Latitude/Longitude
    [HttpGet]
    public async Task<ActionResult<IEnumerable<LocationListViewModel>>> Get(string lat = "", string lng = "")
    {
        if (string.IsNullOrEmpty(lat) && string.IsNullOrEmpty(lng))
        {
            return await _locationService.GetRestaurantsAsync();
        }
        else
        {
            return await _locationService.GetRestaurantsByLatLngAsync(lat, lng);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-22
      • 2021-08-31
      • 2020-04-26
      • 2021-09-07
      • 2022-11-24
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      相关资源
      最近更新 更多