代码之家  ›  专栏  ›  技术社区  ›  WingiM

REST API-如何实现具有相同名称但可接受参数类型不同的多个方法

  •  0
  • WingiM  · 技术社区  · 1 年前

    比方说我想要实现一个用户API控制器。客户端需要通过整数ID获取用户,所以我创建了一个方法 GET - /api/User/{id:int}

    然后出于某种原因,我想实现按用户名获取用户。最明显的解决方案是创建 GET - /api/User/{name:string} 但是这种方法将与之前的方法相冲突。命名方法 /api/UserByName/{name:string} 违反REST实体规则。

    如何在不违反REST规则的情况下处理此问题?

    更新:我刚刚写了以下代码来创建多个路由:

    [HttpGet]
    public async Task<IActionResult> Get([FromQuery] int id)
    {
        return Ok();
    }
    
    [HttpGet]
    public async Task<IActionResult> Get([FromQuery] string name)
    {
        return Ok();
    }
    

    此代码无法通过swagger进行翻译,并产生错误:

    Swashbuckle.AspNetCore.SwakerGen.SwakerGeneratorException:操作的方法/路径组合“GET WeatherForecast”冲突-WebApiSkeleton.API.Contro llers。WeatherForecastController.Get(WebApiSleton.neneneba API)、WebApiSketon.API.Controllers.WeatherForecastControlller.Get(webApiSletleton.nenenebb API)。操作需要 Swagger/OpenAPI 3.0的独特方法/路径组合。使用冲突操作解决方案作为解决方法

    调用方法会引发另一个异常:

    Microsoft.AspNetCore.Routing.Matching.AmbiqueMatchException:请求与多个终结点匹配。匹配项:
    WebApiSketleton.API.Controllers.WeatherForecastController.Get(WebApiSletleton.neneneba API)
    WebApiSketleton.API.Controllers.WeatherForecastController.Get(WebApiSletleton.neneneba API)

    0 回复  |  直到 1 年前
        1
  •  1
  •   Camadas    1 年前

    我使用[FromQuery]的意思是这样的。 它要求你有一个id和name的类

    public class UserFilter
    {
        public int? Id { get; set; }
        public string Name { get; set; }
    }
    

    那就这样走吧

    [HttpGet]
    public async Task<IActionResult> Get([FromQuery] UserFilter filter)
    {
        if (filter.Id.HasValue)
        {
            // Search by id
        }
        else if (!string.IsNullOrWhiteSpace(filter.Name))
        {
            // Searh by name
        }
        return BadRequest();
    }
    
        2
  •  1
  •   Abdelkrim    1 年前

    ASP.Net核心路由使用 precedence in selecting routes ,通常从更具体到通用。因此,如果您有两个路由,一个带有{id:int},另一个没有任何限定符或:alpha限定符,那么如果您发送一个int,则{id:int}将被命中,否则,另一条更通用的路由将被命中。这意味着这两条路线可以共存,并且可以做你想做的事情:

    [HttpGet("something/{id:int}")]
    public IActionResult Get1(int id)
    {
        return Ok();
    }
    
    [HttpGet("something/{id}")]
    public IActionResult Get2(string id)
    {
        return Ok();
    }
    

    您可以使用poster或任何http客户端测试调用这两个enpoint。 您遇到的错误可能与swagger无法生成文档有关,文档内容如下: Conflicting method/path combination 这与asp.net的核心无关,只是虚张声势。

    您可以忽略从swagger中获取{id:int}的那个,因为它不太通用。您可以使用: [ApiExplorerSettings(IgnoreApi = true)] 为此。 一旦你这样做了,如果你打开swagger,你会看到一个端点,但如果你用int尝试它,你会碰到{id:int}端点,否则你会碰到{id}端点。

        3
  •  0
  •   Jeevan ebi    1 年前
    [HttpGet]
    [Route("api/controller")]
    public async Task<IHttpActionResult> Get([FromQuery]string parameter)
    {
        if (!string.IsNullOrEmpty(parameter))
        {
            if (int.TryParse(parameter, out int id))
            {
                // Logic to retrieve data based on the ID asynchronously
                // Example: var data = await repository.GetDataByIdAsync(id);
                // return Ok(data);
            }
            else
            {
                // Logic to retrieve data based on the name asynchronously
                // Example: var data = await repository.GetDataByNameAsync(parameter);
                // return Ok(data);
            }
        }
    
        // Handle invalid or missing parameter
        return BadRequest("Invalid parameter.");
    }
    

    在这个更新的示例中,GetData方法采用字符串类型的单个参数参数。它检查参数是否为null或为空。如果它不为空,它会尝试使用int.TryParse()将其解析为整数。如果解析成功,它会将参数视为ID,并执行基于ID检索数据的逻辑。如果解析失败,它会把参数视为名称,并执行根据名称检索数据的逻辑。

    示例端点:

    按整数:

    GET /api/controller?parameter=123
    

    按字符串:

    GET /api/controller?parameter=SOMENAME