本文介绍了Web Api Core 2独特的GET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么Web API Core 2不能区分这些?

Why can't Web API Core 2 tell these apart?

    [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}";
    }

发生了什么事-

http:// localhost:65528 / api / values http:// localhost:65528 / api / values?name = dave 使第一个 Get()方法执行。

Both http://localhost:65528/api/values and http://localhost:65528/api/values?name=dave cause the first Get() method to execute.

此确切的代码在Web Api 2中正常工作。

This exact code works fine in Web Api 2.

I ,但是我不知道为什么发生。

I know multiple ways of getting around this, but I don't know why it happens.

有人可以解释一下为什么改变了吗?

Can someone explain why this has changed?

推荐答案

我不知道认为您甚至可以在 ASP.NET Core Mvc 2.0 中编译代码,因为您有2个动作映射到同一路由 [HttGet] api / values

I don't think you can even compile your code in ASP.NET Core Mvc 2.0 since you have 2 actions mapped to same route [HttGet] api/values:

AmbiguousActionException: Multiple actions matched.

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

Remember, ASP.NET Web API uses the HTTP verb as part of the request to figure which action to call. Although it uses conventional routing (you name your actions Get, Post, Put and Delete, etc) if you don't have route attribute specify, I would highly recommend to always use routing attribute to annotate your controllers and actions.

现在,由您来设计路线,由开发人员决定。请记住,该路线应该是可以识别一种或多种资源的 Uri

Now it's up to you to design the route, as a developer. Remember the route is supposed to be a Uri that can identify a resource / resources.


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

  • Use the name as identifier along with the route

[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)
    {
        ...
    }
}


  • 使用该名称作为过滤器,针对资源集合

  • Use the name as filter, against the resource collection

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


  • api / customers / dave 仍将首先执行 GetById

    [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 GetById 是潜在的候选者,但是MVC首先选择 GetById 方法,因为MVC比较了方法/模板通过case-ins名称 {name} {id} 字符串比较,并且 i n 之前。

    Both methods GetByName and GetById are potential candidates but MVC picks GetById method first because MVC compares the method/template name {name} and {id} through case-insensitive string comparison, and i comes before 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)
        {
            ...
        }
    }
    

    您也可以指定订购

    [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} {name} 的字符n之前。但是,如果您指定顺序,MVC会根据 Order 来选择操作。

    Without the Order, the method GetByCity will be in favor than GetByName because character c of {city} comes before the character n of {name}. But if you specify the order, MVC will pick the action based on the Order.

    长....

    这篇关于Web Api Core 2独特的GET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    09-27 15:37