Было найдено несколько действий, которые соответствуют веб-API запроса?
Я использую web API, и я новичок в этом. Я застрял в проблеме маршрутизации. У меня есть контроллер со следующими действиями:
// GET api/Ceremony
public IEnumerable<Ceremony> GetCeremonies()
{
return db.Ceremonies.AsEnumerable();
}
// GET api/Ceremony/5
public Ceremony GetCeremony(int id)
{
Ceremony ceremony = db.Ceremonies.Find(id);
return ceremony;
}
public IEnumerable<Ceremony> GetFilteredCeremonies(Search filter)
{
return filter.Ceremonies();
}
Проблема возникает, когда я добавил действие GetFilteredCeremonies
на мой контроллер. После добавления этого, когда я делаю вызов ajax для действия GetCeremonies
, он возвращает исключение со следующим сообщением:
"Message":"An error has occurred.","ExceptionMessage":"Multiple actions were
found that match the request
FYI: Параметр Search
- это класс Model, который содержит свойства и имя функции Ceremonies.
ИЗМЕНИТЬ
Маршрут:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Ответы
Ответ 1
Если вы не обязаны использовать службы REST, которые используют маршрут api/{controller}/{id}
и пытаются разрешить действие на основе метода GET/ POST/ УДАЛИТЬ/ PUT, вы можете изменить свой маршрут на классический маршрут MVC до api/{controller}/{action}/{id}
, и он решит ваши проблемы.
Ответ 2
Проблема здесь в том, что методы 2 Get
будут разрешены для api/Ceremony
, а MVC не разрешает перегрузку параметров. Быстрое обходное решение (не обязательно предпочтительный подход) для этой проблемы заключается в том, чтобы сделать параметр id
равным нулю, например.
// GET api/Ceremony
public IEnumerable<Ceremony> GetCeremonies(int? id)
{
if (id.HasValue)
{
Ceremony ceremony = db.Ceremonies.Find(id);
return ceremony;
}
else
{
return db.Ceremonies.AsEnumerable();
}
}
Тем не менее, вы должны были бы вернуть список церемоний, когда с 1 пунктом, когда вы пытаетесь запросить одну церемонию - если вы можете с ней жить, тогда это может быть решением для вас.
Рекомендуемое решение - правильно сопоставить ваши пути с правильными действиями, например.
context.Routes.MapHttpRoute(
name: "GetAllCeremonies",
routeTemplate: "api/{controller}",
defaults: new { action = "GetCeremonies" }
);
context.Routes.MapHttpRoute(
name: "GetSingleCeremony",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "GetCeremony", id = UrlParameter.Optional }
);
Ответ 3
К счастью, в настоящее время с WEB API2 вы можете использовать Маршрутизация атрибутов. Microsoft стала открытым исходным кодом в большом масштабе, а затем мастер по имени Тим Макколл внес ее в сообщество. Поэтому, начиная с конца 2013 года, в начале 2014 года, вы можете добавлять атрибуты типа [Route("myroute")]
в свои методы веб-интерфейса. Пример кода ниже.
Тем не менее, как я только что узнал, вы должны использовать System.Web.Http.Route
и NOT System.Web.Mvc.Route
. В противном случае вы получите сообщение об ошибке Multiple actions were found that match the request
.
using System.Web.Http;
...
[Route("getceremonies")]
[HttpGet]
// GET api/Ceremony
public IEnumerable<Ceremony> GetCeremonies()
{
return db.Ceremonies.AsEnumerable();
}
[Route("getceremony")]
[HttpGet]
// GET api/Ceremony/5
public Ceremony GetCeremony(int id)
{
Ceremony ceremony = db.Ceremonies.Find(id);
return ceremony;
}
[Route("getfilteredceremonies")]
[HttpGet]
public IEnumerable<Ceremony> GetFilteredCeremonies(Search filter)
{
return filter.Ceremonies();
}
Ответ 4
Вот мой контроллер:
public class PhoneFeaturesController : ApiController
{
public List<PhoneFeature> GetbyPhoneId(int id)
{
var repository = new PhoneFeatureRepository();
return repository.GetFeaturesByPhoneId(id);
}
public PhoneFeature GetByFeatureId(int id)
{
var repository = new PhoneFeatureRepository();
return repository.GetFeaturesById(id);
}
}
Вот моя маршрутизация api:
config.Routes.MapHttpRoute(
name: "ApiWithId",
routeTemplate: "Api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"^[0-9]+$" });
config.Routes.MapHttpRoute(
name: "ApiWithAction",
routeTemplate: "api/{controller}/{action}/{name}",
defaults: null,
constraints: new { name = @"^[a-z]+$" });
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "Get" },
constraints: new { id = @"^[0-9]+$" });
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Я протестировал его так:
/api/PhoneFeatures//api/PhoneFeatures/GetFeatureById/101
/api/PhoneFeatures/GetByFeatureId/12
Он работает гладко в каждом условии:)
Ответ 5
Пожалуйста, проверьте, что у вас есть два метода, которые имеют разные имена и одинаковые параметры.
Если это так, удалите любой из методов и попробуйте.
Эта ошибка была вызвана, потому что есть два метода, которые ищут одинаковые параметры. попробуйте удалить любой из них и попробуйте...
Ответ 6
Я надеюсь, что вы делаете HttpGet, когда вы вызываете GetFilteredCeremonies(Search filter)
В этом случае вы не можете передать сложный объект в запросе GET, например, Search
, который вы передаете.
Если по какой-то причине вы определенно хотите получить сложные типы в своем запросе на получение, есть некоторые проблемы. Возможно, вам придется написать настраиваемое связующее устройство, а затем установить атрибут. пожалуйста, обратитесь к этой статье.
Ответ 7
Отредактируйте WebApiConfig.cs в папке App_Start в корне проекта и добавьте {действие} в параметр routeTemplate в MapHttpRoute. Метод, как показано ниже.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);