В исходном коде webapi вы используете Routes.MapHttpRoute
, который добавляет особые маршруты webapi. Это отличается от маршрута MVC, который не учитывает параметры в действии, например, у вас была бы такая же проблема в MVC 5, если вы использовали Routes.MapRoute
.
То же самое происходит в коде MVC 6, поскольку вы добавляете стандартный маршрут MVC с использованием routes.MapRoute
. В обоих случаях структура обнаруживает 2 действия контроллера, соответствующие одному и тому же маршруту, без каких-либо дополнительных ограничений. Для того, чтобы выбрать одно из этих двух действий, нужна некоторая помощь.
Самый простой способ неоднозначность действия API будет использовать атрибут маршрутизации вместо определения маршрута, как в this example:
[Route("v1/[controller]")]
public class UsersController : Controller
{
[HttpGet("{id:int}")]
public IActionResult Users(long id)
{
return Json(new { name = "Example User" });
}
public IActionResult Users()
{
return Json(new { list = new[] { "a", "b" } });
}
}
Есть другие варианты, которые позволят вам изменить поведение маршрутизации MVC в MVC 6. Вы можете создать свой собственный атрибут IActionConstraint
, чтобы обеспечить наличие или отсутствие данного параметра. Таким образом, один из этих действий требует идентификатор параметра в маршруте, а другой требует, чтобы не иметь параметр ID (предупреждение, непроверенный код):
public class UsersController : Controller
{
[RouteParameterConstraint("id", ShouldAppear=true)]
public IActionResult Users(long id)
{
return Json(new { name = "Example User" });
}
[RouteParameterConstraint("id", ShouldNotAppear=true)]
public IActionResult Users()
{
return Json(new { list = new[] { "a", "b" } });
}
}
public class RouteParameterConstraintAttribute : Attribute, IActionConstraint
{
private routeParameterName;
public RouteParameterConstraintAttribute(string routeParameterName)
{
this.routerParamterName = routerParameterName;
}
public int Order => 0;
public bool ShouldAppear {get; set;}
public bool ShouldNotAppear {get; set;}
public bool Accept(ActionConstraintContext context)
{
if(ShouldAppear) return context.RouteContext.RouteData.Values["country"] != null;
if(ShouldNotAppear) return context.RouteContext.RouteData.Values["country"] == null;
return true;
}
}
лучший вариант, чтобы иметь дело с контроллерами WebAPI 2 типа будет добавлять соглашения в конвейере MVC. Это именно то, что делает Microsoft.AspNet.Mvc.WebApiCompatShim
, чтобы помочь переносить контроллеры webapi 2. Вы можете видеть соглашения, добавленные here. Проверьте this guide для краткого обзора этого пакета.
Я собираюсь угадать, что у вас есть атрибут 'Route' на вашем контроллере, который есть во многих шаблонах. Можете ли вы предоставить весь ваш контроллер? –
@MattDeKrey Я не думаю, что они были бы нужны, если бы я просто установил свои маршруты, как webapi 2 маршрута – Gazeth