Web Api Core 2 区分 GET

2024-01-12

为什么 Web API Core 2 无法区分它们?

    [HttpGet]
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values?name=dave
    [HttpGet]
    public string Get(string name)
    {
        return $"name is {name}";
    }

发生的事情是这样的——

Both http://localhost:65528/api/values and http://localhost:65528/api/values?name=dave导致第一个Get()方法来执行。

这段代码在 Web Api 2 中运行良好。

I know http://nodogmablog.bryanhogan.net/2017/07/net-core-web-api-routing/ multiple http://nodogmablog.bryanhogan.net/2017/08/net-core-multiple-get-methods-with-the-action-method-selector-attribute/解决这个问题的方法,但我不知道why它发生了。

有人可以解释为什么这种情况发生了变化吗?


我认为你甚至不能编译你的代码ASP.NET Core Mvc 2.0因为您有 2 个操作映射到同一路线[HttGet] api/values:

AmbiguousActionException: Multiple actions matched.

记住,ASP.NET Web API使用 HTTP 动词作为请求的一部分来确定要调用哪个操作。尽管它使用传统路由(您将操作命名为 Get、Post、Put 和 Delete 等),但如果您没有指定路由属性,我强烈建议您始终使用路由属性来注释您的控制器和操作。

API设计时间

现在由您作为开发人员来设计路线。请记住该路线应该是Uri可以识别一个/多个资源。

  • 使用名称作为路线的标识符

    [Route("api/[controller]")]
    public class CustomersController : Controller
    {
        // api/customers
        [HttpGet]
        public IActionResult Get()
        {
           ...
        }
    
        // api/customers/dave
        [HttpGet("{name:alpha}")]     // constraint as a string 
        public IActionResult GetByName(string name)
        {
            ...
        }
    }
    
  • 使用名称作为过滤器,针对资源集合

    [Route("api/[controller]")]
    public class CustomersController : Controller
    {
        // api/customers
        // api/customers?name=dave
        [HttpGet]
        public IActionResult Get(string name)
        {
            ...
        }
    }
    

让你更加迷惑

api/customers/dave仍会执行GetById first!

[Route("api/[controller]")]
public class CustomersController : Controller
{
    [HttpGet]
    public IActionResult Get()
    {
        ...
    }

    [HttpGet("{name}")]
    public IActionResult GetByName(string name)
    {
        ...
    }

    [HttpGet("{id}")]
    public IActionResult GetById(int id)
    {
        ...
    }
}

两种方法GetByName and GetById是潜在的候选人,但 MVC 选择GetById方法优先,因为 MVC 会比较方法/模板名称{name} and {id}通过不区分大小写的字符串比较,以及i出现在之前n.

这时候你想把限制条件.

[Route("api/[controller]")]
public class CustomersController : Controller
{
    [HttpGet]
    public IActionResult Get()
    {
        ...
    }

    // api/customers/dave
    [HttpGet("{name:alpha}")]
    public IActionResult GetByName(string name)
    {
        ...
    }

    // api/customers/3
    [HttpGet("{id:int}")]
    public IActionResult GetById(int id)
    {
        ...
    }
}

您还可以指定Ordering too!

[Route("api/[controller]")]
public class CustomersController : Controller
{
    [HttpGet]
    public IActionResult Get()
    {
        ...
    }

    // api/customers/portland
    [HttpGet("{city:alpha}", Order = 2)]
    public IActionResult GetByCity(string city)
    {
        ...
    }

    // api/customers/dave
    [HttpGet("{name:alpha}", Order = 1)]
    public IActionResult GetByName(string name)
    {
        ...
    }

    // api/customers/3
    [HttpGet("{id:int}")]
    public IActionResult GetById(int id)
    {
        ...
    }
}

如果没有Order, 方法GetByCity会比GetByName因为字符 c 的{city}出现在字符 n 之前{name}。但如果您指定顺序,MVC 将根据Order.

唉,帖子太长了……

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Web Api Core 2 区分 GET 的相关文章

随机推荐