Как перегрузить методы контроллера с тем же количеством аргументов в ASP.NET Основной веб-API?

#routing #asp.net-core-webapi #asp.net-web-api-routing #asp.net-core-2.2

#маршруты #asp.net-core-webapi #asp.net-web-api-routing #asp.net-core-2.2

Вопрос:

Я переношу полный.NET Framework Web API 2 REST project переходит на ASP.NET Ядро 2.2 и немного теряется в маршрутизации.

В Web API 2 я смог перегрузить маршруты с одинаковым количеством параметров на основе типа параметра, например, я мог бы иметь Customer.Get(int ContactId) и Customer.Get(DateTime includeCustomersCreatedSince) , и входящие запросы будут маршрутизироваться соответствующим образом.

Я не смог добиться того же в .NET Core, вместо этого я получаю ошибку 405 или 404 и эту ошибку:

«{«ошибка»:»Запрос соответствовал нескольким конечным точкам. Соответствует: rnrn[AssemblyName].Контроллеры.CustomerController.Get ([AssemblyName])r n[AssemblyName].Контроллеры.CustomerController.Get ([AssemblyName])»}»

Это был рабочий код в моем полном объеме.Приложение NET framework app Web API 2 app:

 [RequireHttps]    
public class CustomerController : ApiController
{
    [HttpGet]
    [ResponseType(typeof(CustomerForWeb))]
    public async Task<IHttpActionResult> Get(int contactId)
    {
       // some code
    }

    [HttpGet]
    [ResponseType(typeof(List<CustomerForWeb>))]
    public async Task<IHttpActionResult> Get(DateTime includeCustomersCreatedSince)
    {
        // some other code
    }
}
  

И это то, к чему я преобразовал его в Core 2.2:

 [Produces("application/json")]
[RequireHttps]
[Route("api/[controller]")]
[ApiController]
public class CustomerController : Controller
{
    public async Task<ActionResult<CustomerForWeb>> Get([FromQuery] int contactId)
    {
        // some code
    }

    public async Task<ActionResult<List<CustomerForWeb>>> Get([FromQuery] DateTime includeCustomersCreatedSince)
    {
        // some code
    }
}
  

Приведенный выше код работает, если я закомментирую один из Get методов, но завершается неудачей, как только у меня есть два Get метода. Я ожидал, что FromQuery будет использовать имя параметра в запросе для управления маршрутизацией, но, похоже, это не так?

Возможно ли перегрузить подобный метод контроллера, где у вас одинаковое количество параметров и либо маршрут, основанный на типе параметра, либо имя параметра?

Ответ №1:

Вы не можете выполнять перегрузки действий. Способ маршрутизации работает в ASP.NET Ядро отличается от того, как это было в ASP.NET Веб-Api. Однако вы можете просто объединить эти действия, а затем перейти внутрь, поскольку все параметры являются необязательными:

 public async Task<ActionResult<CustomerForWeb>> Get(int contactId, DateTime includeCustomersCreatedSince)
{
    if (contactId != default)
    {
        ...
    }
    else if (includedCustomersCreatedSince != default)
    {
        ...
    }
}
  

Комментарии:

1. Ах, это все объясняет! Что бы произошло, если бы у вас было два параметра одного типа, например, Get(int companyId, int personId) и вы хотели бы использовать только PersonID, вам нужно было бы вызвать Customer/Get?personId=1234 ? Т. е. использует ли маршрутизация тип параметра или имя параметра для сопоставления?

2. ДА. Он будет привязан через имя.

3. Я не понимаю, почему они не позволили перегружать методы для разных параметров… Make If/else-if/else-if/..../else очень неприятно, когда вы имеете дело с параметрами строки запроса, которые могут быть объединены вместе или нет…

Ответ №2:

Вы можете просто использовать разные маршруты для каждого метода, например

     [HttpPost("add")]
    public void add(string StringParam)
    {
    }

    [HttpPost("add-overload-1")]
    public void add(int IntParam)
    {
    }


    [HttpPost("add-overload-2")]
    public void add(bool BoolParam)
    {
    }