Как перегрузить методы контроллера с одинаковым количеством аргументов в ASP.NET Core Web API?

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

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

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

"{\"error\":\"The request matched multiple endpoints. Matches: \r\n\r\n[AssemblyName].Controllers.CustomerController.Get ([AssemblyName])\r\n[AssemblyName].Controllers.CustomerController.Get ([AssemblyName])\"}"

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

[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 будет использовать имя параметра в запросе для управления маршрутизацией, но, похоже, это не так?

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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
4 623
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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

tomRedox 08.04.2019 15:35

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

Chris Pratt 08.04.2019 15:50

Не понимаю, почему не сделали возможность перегружать методы для разных параметров... Делать If/else-if/else-if/..../else очень неприятно, когда имеешь дело с параметрами QueryString, которые можно комбинировать между собой или нет...

vincenthavinh 01.07.2019 10:07

Другие вопросы по теме