259 votes

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

Je continue à obtenir cette erreur lorsque j'essaie d'avoir deux méthodes "Get".

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

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

J'ai 2 noms différents et j'utilise l'attribut "HttpGet".

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

[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}

506voto

Jed Points 1170

Votre feuille de route est probablement quelque chose comme ça :

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 });

Remarquez que le routeTemplate comprend maintenant 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 avoir compris ce que vous recherchez, voici une autre façon de voir les choses :

Peut-être n'avez-vous pas besoin du paramètre url de l'action et devriez-vous 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 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 passez-vous dans l'objet MyVm ? Si vous pouvez simplement passer des variables à travers l'URI, je vous suggère de suivre cette voie. Sinon, vous devrez envoyer l'objet dans le corps de la requête et ce n'est pas très HTTP de votre part lorsque vous faites un GET (cela fonctionne cependant, utilisez simplement [FromBody] devant MyVm).

Nous espérons que cela montre 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].

0 votes

Y a-t-il des avantages à procéder d'une manière ou d'une autre ? Si je fais la méthode secondaire, dois-je simplement placer l'action Http sur chaque méthode ? Est-ce là le principal inconvénient ?

3 votes

L'avantage de l'un par rapport à l'autre dépend vraiment de votre projet. Si vous construisez une API RESTful, vous voudrez alors utiliser les conventions HTTP (GET, POST, PUT, DELETE...). Dans ce cas, le premier bloc de code de routage est la voie à suivre, mais vous voudrez un contrôleur différent pour chaque entité que vous exposez via l'API. D'après les noms de vos méthodes, je suppose que ce n'est pas le cas, donc utilisez le routage plus descriptif. Lorsque votre route inclut l'action, vous devez explicitement mettre l'attribut http sur chaque méthode.

0 votes

Mais ne pouvez-vous pas utiliser les conventions restful même si vous utilisez la deuxième méthode si vous mettez simplement le bon attribut sur chaque méthode ? Eh bien, je ne peux vraiment pas le décomposer en une entité séparée. Je veux dire que ce sont les mêmes données, mais en moins grand nombre. Bien sûr, je pourrais n'avoir qu'une seule méthode get et toujours renvoyer toutes les données et laisser le client s'en occuper, mais si l'appareil est un appareil mobile, vous voulez vraiment renvoyer le moins de données possible, sinon vous gaspillez les données d'une personne, ce qui peut être coûteux.

15voto

Filip W Points 13343

Dans l'API Web (par défaut), les méthodes sont choisies sur la base d'un critère de sélection. combinaison des valeurs de la méthode HTTP et de la route .

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

Vous devez les différencier par une chaîne de requête ou un paramètre de route pour résoudre l'ambiguïté.

14voto

Moatasem bk Points 50

Après avoir beaucoup cherché sur le web et essayé de trouver le formulaire le plus approprié pour la carte de routage j'ai 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 aux noms des actions et aux conventions http de base (GET, POST, PUT, DELETE).

9 votes

Pour moi, cela a fonctionné, mais seulement après avoir changé l'ordre des routes dans la configuration des routes afin que celle avec l'action apparaisse en premier.

0 votes

L'ordre exact est important ici

5voto

Max Points 1230

Il est possible que vos webmethods soient résolus vers la même url. Jetez un coup d'œil au lien suivant :-

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

Vous devrez donc peut-être ajouter votre nom de méthode à votre table de routage.

5voto

Joanna Turban Points 2521

Sans utiliser les actions, les options seraient :

  1. déplacer l'une des méthodes vers un autre contrôleur, afin d'éviter tout conflit.

  2. utilisez une seule méthode qui prend le paramètre, et si celui-ci est nul, appelez l'autre méthode de votre code.

0 votes

C'est peut-être une solution, mais pas la meilleure, en tout cas +1 de mon côté :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X