Plusieurs actions ont été trouvées qui correspondent à la demande dans L'Api Web

Je continue à avoir cette erreur quand j'essaie d'avoir 2 méthodes " Get "

Plusieurs actions correspondant à la requête ont été trouvées: webapi

J'ai regardé autour des autres questions similaires à ce sujet sur stack mais je ne comprends pas.

J'ai 2 noms différents et en utilisant l'attribut "HttpGet"

[HttpGet]
public HttpResponseMessage Summary(MyVm vm)
{
    return null;
}

[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}
202
demandé sur abatishchev 2013-01-26 09:27:51

13 réponses

Votre carte d'itinéraire est probablement quelque chose comme ceci:

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });

Mais pour avoir plusieurs actions avec la même méthode http, vous devez fournir à webapi plus d'informations via la route comme ceci:

routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });

Notez que routeTemplate inclut désormais une action. Beaucoup plus d'informations ici: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

Mise à Jour:

Très bien, maintenant que je pense que je comprends ce que vous êtes après voici une autre prise à ceci:

Peut-être que vous n'avez pas besoin du paramètre url d'action et que vous devez décrire le contenu que vous recherchez d'une autre manière. Puisque vous dites que les méthodes renvoient des données de la même entité, laissez simplement les paramètres faire la description pour vous.

Par exemple, vos deux méthodes pourraient être transformées en:

public HttpResponseMessage Get()
{
    return null;
}

public HttpResponseMessage Get(MyVm vm)
{
    return null;
}

Quel type de données transmettez-vous dans L'objet MyVm? Si vous êtes capable de simplement passer des variables à travers L'URI, je le ferais suggère d'aller dans cette voie. Sinon, vous devrez envoyer l'objet dans le corps de la requête et ce N'est pas très HTTP lorsque vous faites un GET (cela fonctionne cependant, utilisez simplement [FromBody] en face de MyVm).

Espérons que cela illustre que vous pouvez avoir plusieurs méthodes GET dans un seul contrôleur sans utiliser le nom de l'action ou même l'attribut [HttpGet].

396
répondu Jed 2014-01-25 05:40:41

Mise à jour à partir de L'API Web 2.

Avec cette configuration D'API dans votre WebApiConfig.fichier cs:

public static void Register(HttpConfiguration config)
{
    //// Web API routes
    config.MapHttpAttributeRoutes(); //Don't miss this

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = System.Web.Http.RouteParameter.Optional }
    );
}

, Vous pouvez acheminer notre contrôleur comme ceci:

[Route("api/ControllerName/Summary")]
[HttpGet]
public HttpResponseMessage Summary(MyVm vm)
{
    rturn null;
}

[Route("api/ControllerName/FullDetails")]
[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}

Où ControllerName est le nom de votre contrôleur (sans "controller"). Cela vous permettra d'obtenir chaque action avec l'itinéraire détaillé ci-dessus.

Pour en savoir plus: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

49
répondu Marc Stevenson 2016-01-21 21:10:44

Dans L'API Web (par défaut), les méthodes sont choisies en fonction d'une combinaison de valeurs de méthode HTTP et de route .

MyVm on dirait un objet complexe, lu par le formateur à partir du corps, donc vous avez deux méthodes identiques en termes de données de route (car aucune d'entre elles n'a de paramètres de la route) - ce qui rend impossible pour le répartiteur (IHttpActionSelector) de correspondre à celui approprié.

Vous devez les différer par le paramètre querystring ou route pour résoudre l'ambiguïté.

14
répondu Filip W 2013-05-10 19:58:44

Après beaucoup de recherche sur le web et d'essayer de trouver la forme la plus appropriée pour la carte de routage si vous avez trouvé ce qui suit

config.Routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id =RouteParameter.Optional }, new { id = @"\d+" });
config.Routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}");

Ces mappages s'appliquent à la fois au mappage des noms d'action et à la convention http de base (GET,POST,PUT,DELETE)

10
répondu Moatasem bakri 2014-10-23 04:40:41

Il est possible que vos webmethods soient résolus vers la même url. Jetez un oeil sur le lien suivant :-

Http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

Donc, vous devrez peut-être ajouter votre nom de méthode à votre table de routage.

4
répondu Max 2013-01-26 05:35:22

Sans utiliser d'actions, les options seraient:

  1. Déplacez l'une des méthodes vers un contrôleur différent, afin qu'elles ne s'affrontent pas.

  2. Utilisez une seule méthode qui prend le paramètre, et s'il est null, appelez l'autre méthode à partir de votre code.

4
répondu Joanna Derks 2013-01-26 14:35:42

J'ai trouvé que lorsque j'ai deux méthodes Get, une sans paramètre et une avec un type complexe comme paramètre, j'ai eu la même erreur. J'ai résolu cela en ajoutant un paramètre factice de type int, nommé Id, comme premier paramètre, suivi de mon paramètre de type complexe. J'ai ensuite ajouté le paramètre type complexe au modèle de route. Ce qui suit a fonctionné pour moi.

Obtenez D'abord:

public IEnumerable<SearchItem> Get()
{
...
}

Deuxième obtenir:

public IEnumerable<SearchItem> Get(int id, [FromUri] List<string> layers)
{
...
}

WebApiConfig:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}/{layers}",
    defaults: new { id = RouteParameter.Optional, layers RouteParameter.Optional }
);
3
répondu Andrew Terwiel 2015-03-25 22:35:08

Veuillez vérifier que vous avez deux méthodes qui ont le nom différent et les mêmes paramètres.

Si c'est le cas, supprimez l'une des méthodes et essayez.

2
répondu Ramesh 2013-07-10 18:16:17

Je suis tombé sur ce problème en essayant d'augmenter mes contrôleurs WebAPI avec des actions supplémentaires.

Supposons que vous auriez

public IEnumerable<string> Get()
{
    return this.Repository.GetAll();
}

[HttpGet]
public void ReSeed()
{
    // Your custom action here
}

Il existe maintenant deux méthodes qui satisfont la demande de/api / controller qui déclenche le problème décrit par TS.

Je ne voulais pas ajouter de paramètres "fictifs" à mes actions supplémentaires, alors j'ai regardé dans les actions par défaut et j'ai trouvé:

[ActionName("builtin")]
public IEnumerable<string> Get()
{
    return this.Repository.GetAll();
}

Pour la première méthode en combinaison avec la route" dual" liaison:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "builtin", id = RouteParameter.Optional },
    constraints: new { id = @"\d+" });

config.Routes.MapHttpRoute(
    name: "CustomActionApi",
    routeTemplate: "api/{controller}/{action}");

Notez que même s'il n'y a pas de paramètre "action" dans le premier modèle de route apparemment, vous pouvez toujours configurer une action par défaut nous permettant de séparer le routage des appels WebAPI "normaux" et les appels à l'action supplémentaire.

2
répondu Bjørn van Dommelen 2015-06-04 13:03:17

C'est possible en utilisant MVC controller au lieu de web API controller. Vérifiez l'espace de noms dans le contrôleur D'API Web, il devrait être comme suit

using System.Net;
using System.Net.Http;
using System.Web.Http;

Si l'espace de noms est comme suit, il est donné ci-dessus erreur dans la méthode de contrôleur d'api web appelant

using System.Web;
using System.Web.Mvc;
2
répondu Ujwal Khairnar 2017-10-20 08:50:39

Cette solution a fonctionné pour moi.

Veuillez placer Route2 en premier dans WebApiConfig. Ajoutez également HttpGet et HttpPost avant chaque méthode et incluez le nom du contrôleur et le nom de la méthode dans l'url.

WebApiConfig =>

config.Routes.MapHttpRoute(
           name: "MapByAction",
           routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional });
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional });

Contrôleur = >

public class ValuesController : ApiController
{

    [HttpPost]
    public string GetCustomer([FromBody] RequestModel req)
    {
        return "Customer";
    }

    [HttpPost]
    public string GetCustomerList([FromBody] RequestModel req)
    {
        return "Customer List";
    }
}

Url = >

http://localhost:7050/api/Values/GetCustomer

http://localhost:7050/api/Values/GetCustomerList
2
répondu Alan Rezende 2018-03-31 04:03:57

Je sais que c'est une vieille question, mais parfois, lorsque vous utilisez des ressources de service comme de AngularJS pour vous connecter à WebAPI, assurez-vous d'utiliser la bonne route, sinon cette erreur se produit.

0
répondu Suresh Kaushik 2017-06-20 15:40:37

Assurez-vous de ne pas décorer vos méthodes de contrôleur pour les actions GET|PUT|POST|DELETE par défaut avec l'attribut [HttpPost/Put/Get/Delete]. J'avais ajouté cet attibute à mon action de contrôleur de poste de vanille et cela a provoqué un 404.

J'espère que cela aide quelqu'un car cela peut être très frustrant et arrêter les progrès.

0
répondu ComeIn 2017-09-06 00:47:20