Подтвердить что ты не робот

Было найдено несколько действий, которые соответствуют веб-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 }
            );
4b9b3361

Ответ 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 }
        );