Я переношу полный проект .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
будет использовать имя параметра в запросе для управления маршрутизацией, но, похоже, это не так?
Можно ли перегрузить такой метод контроллера, если у вас одинаковое количество параметров и либо маршрут на основе типа параметра, либо имени параметра?
Вы не можете выполнять перегрузку действий. Способ работы маршрутизации в ASP.NET Core отличается от того, как он работал в ASP.NET Web Api. Однако вы можете просто объединить эти действия, а затем перейти внутрь, так как все параметры являются необязательными:
public async Task<ActionResult<CustomerForWeb>> Get(int contactId, DateTime includeCustomersCreatedSince)
{
if (contactId != default)
{
...
}
else if (includedCustomersCreatedSince != default)
{
...
}
}
да. Он будет привязан через имя.
Не понимаю, почему не сделали возможность перегружать методы для разных параметров... Делать If/else-if/else-if/..../else
очень неприятно, когда имеешь дело с параметрами QueryString, которые можно комбинировать между собой или нет...
А, это объясняет! Что произойдет, если у вас будет два параметра одного типа, например.
Get(int companyId, int personId)
и вы хотели использовать только personId, нужно ли вам звонитьCustomer/Get?personId=1234
? т.е. использует ли маршрутизация тип параметра или имя параметра для сопоставления?