.NETCore3.1WebAPI中的多个get方法

.NETCore3.1WebAPI中的多个get方法,.net,api,asp.net-core,.net-core,.net,Api,Asp.net Core,.net Core,我试图用三种get方法创建一个非常基本的控制器 下面是他们的三个uri 获取/电影-获取所有电影 GET/movies?name={name}`-查找与指定名称匹配的所有电影 Get/Movies/{Id}-按Id查找电影 我的控制器代码如下所示 [Route("api/[controller]")] [ApiController] public class MoviesController : ControllerBase { private readonly IM

我试图用三种get方法创建一个非常基本的控制器 下面是他们的三个uri

  • 获取/电影-获取所有电影
  • GET/movies?name={name}`-查找与指定名称匹配的所有电影
  • Get/Movies/{Id}-按Id查找电影
  • 我的控制器代码如下所示

    [Route("api/[controller]")]
    [ApiController]
    public class MoviesController : ControllerBase
    {
        private readonly IMoviesService moviesService;
    
        public MoviesController(IMoviesService moviesService)
        {
            this.moviesService = moviesService;
        }
        
        [HttpGet]
        public async Task<IActionResult> Get()
        {
            var result = await moviesService.GetMoviesAsync();
            return Ok(result);
        }
        
        [HttpGet]
        public async Task<IActionResult> GetByName([FromQuery(Name = "name")] string name)
        {
            var result = await moviesService.GetMoviesByNameAsync(name);
            return Ok(result);
        }
    
        [HttpGet("{Id}", Name = "GetById")]
        public async Task<IActionResult> GetById(Guid Id)
        {
            var result = await moviesService.GetMovieById(Id);
            return Ok(result);
        }       
    
    }
    
    [路由(“api/[控制器]”)]
    [ApiController]
    公共类电影控制器:控制器数据库
    {
    私有只读IMoviesService电影服务;
    公共电影控制器(IMoviesService电影服务)
    {
    this.moviesService=moviesService;
    }
    [HttpGet]
    公共异步任务Get()
    {
    var result=await moviesService.GetMoviesAsync();
    返回Ok(结果);
    }
    [HttpGet]
    公共异步任务GetByName([FromQuery(Name=“Name”)]字符串名称)
    {
    var result=await moviesService.GetMoviesByNameAsync(名称);
    返回Ok(结果);
    }
    [HttpGet(“{Id}”,Name=“GetById”)]
    公共异步任务GetById(Guid Id)
    {
    var result=await moviesService.GetMovieById(Id);
    返回Ok(结果);
    }       
    }
    
    当我通过
    api/movies/31234567-89ab-cdef-0123-456789abcdef
    向GetById发送请求时,它就工作了 但是对于
    api/movies
    api/movies?name=Test
    我得到下面的错误

    请求与多个端点匹配。匹配:MoviesController.Get和MoviesController.GetByName


    考虑到最佳实践,有谁能建议我在web api.net core 3.1中实现此类场景的最佳方法吗?

    您的
    Get
    GetByName
    操作没有为它们提供属性路由,并且都与“api/Movies”匹配。为了解决这个问题,您还需要将路由模板添加到这些操作中的至少一个

    一种可能的解决办法是:

    [HttpGet]
    public async Task<IActionResult> Get()
    {
        var result = await moviesService.GetMoviesAsync();
        return Ok(result);
    }
    
    [HttpGet]
    [Route("{name}")]
    public async Task<IActionResult> GetByName([FromRoute] string name)
    {
        var result = await moviesService.GetMoviesByNameAsync(name);
        return Ok(result);
    }
    
    [HttpGet]
    公共异步任务Get()
    {
    var result=await moviesService.GetMoviesAsync();
    返回Ok(结果);
    }
    [HttpGet]
    [路由(“{name}”)]
    公共异步任务GetByName([FromRoute]字符串名称)
    {
    var result=await moviesService.GetMoviesByNameAsync(名称);
    返回Ok(结果);
    }
    
    请注意,此处具有特定名称的电影的url不再是/movies?name={name},而是/movies/{name}


    如果您绝对希望保留URL/movies?name={name},您可以将
    Get
    GetByName
    操作合并到一个操作中,该操作接受查询字符串参数
    name
    ,并根据其值执行逻辑。

    您最好像
    api/movies/GetByName/{Id}这样更改URL,
    api/Movies/GetById/{Name}

    然后:

  • 获取/电影-获取所有电影
  • GET/movies/GetByName/{name}`-查找与 指定名称
  • Get/Movies/GetById/{Id}-按Id查找电影
  • 在添加其他操作时,您还可以将操作名称添加到路由,这可以帮助您避免请求匹配多个端点。

    下面是一个演示:

            [HttpGet]
            public async Task<IActionResult> Get()
            {
                return Ok();
            }
    
            [HttpGet("GetByName/{name}")]
            public async Task<IActionResult> GetByName(string name)
            {
                return Ok();
            }
    
            [HttpGet("GetById/{Id}")]
            public async Task<IActionResult> GetById(Guid Id)
            {
                return Ok();
            } 
    
    [HttpGet]
    公共异步任务Get()
    {
    返回Ok();
    }
    [HttpGet(“GetByName/{name}”)]
    公共异步任务GetByName(字符串名称)
    {
    返回Ok();
    }
    [HttpGet(“GetById/{Id}”)]
    公共异步任务GetById(Guid Id)
    {
    返回Ok();
    } 
    
    结果:

    @Nishant,您的手机几乎不错,只是做了一些小改动。以下是有效的解决方案。注释内嵌在代码中

    [Route("api/[controller]")]
    [ApiController]
    public class MoviesController : ControllerBase
    {
        //GET /movies - gets all movies.
        [HttpGet]
        public async Task<IActionResult> Get()
        {
            return Ok();
        }
    
        //GET /movies/name={name}` - finds all movies matching the specified name
        [HttpGet("{name}")]  //added the route
        public async Task<IActionResult> GetByName(string name) // modified the input parameter
        {
            return Ok();
        }
    
        //Get /Movies/{Id} - Find movie By Id
        [HttpGet("{Id:guid}", Name = "GetById")] //added the input type
        public async Task<IActionResult> GetById(Guid Id)
        {
            return Ok();
        }
    
    }
    
    [路由(“api/[控制器]”)]
    [ApiController]
    公共类电影控制器:控制器数据库
    {
    //获取/电影-获取所有电影。
    [HttpGet]
    公共异步任务Get()
    {
    返回Ok();
    }
    //GET/movies/name={name}`-查找与指定名称匹配的所有电影
    [HttpGet(“{name}”)]//添加了路由
    公共异步任务GetByName(字符串名称)//修改了输入参数
    {
    返回Ok();
    }
    //Get/Movies/{Id}-按Id查找电影
    [HttpGet(“{Id:guid}”,Name=“GetById”)]//添加了输入类型
    公共异步任务GetById(Guid Id)
    {
    返回Ok();
    }
    }
    

    请让我知道这是否有帮助。

    当使用
    /movies/xxxx
    时,它将获得与多个端点匹配的
    请求。匹配项:WebAPI.Controllers.MoviesController.GetById(WebAPI)WebAPI.Controllers.MoviesController.GetByName(WebAPI)