Je continue à avoir cette erreur lorsque j'essaie d'avoir 2 méthodes "Get"
Plusieurs actions correspondant à la demande ont été trouvées: webapi
J'ai regardé les autres questions similaires à ce sujet sur la pile 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;
}
Votre feuille de route ressemble probablement à 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 l’itinéraire comme ceci:
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional });
Notez que la routeTemplate inclut 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
Mettre à jour:
Bon, maintenant que je pense que je comprends ce que vous êtes ici, voici une autre prise à ceci:
Peut-être n'avez-vous pas besoin du paramètre d'action url 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 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 à l'objet MyVm? Si vous pouvez simplement passer des variables via l'URI, je vous conseillerais de suivre cette voie. Sinon, vous devrez envoyer l'objet dans le corps de la requête, ce qui n'est pas très HTTP lorsque vous effectuez une opération GET (cela fonctionne cependant, utilisez simplement [FromBody] en face de MyVm).
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 ni même l'attribut [HttpGet].
Mise à jour à partir de l'API Web 2.
Avec cette configuration d'API dans votre fichier WebApiConfig.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 "contrôleur"). 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
Dans l'API Web (par défaut), les méthodes sont choisies en fonction de la combinaison de la méthode HTTP et des valeurs d'itinéraire .
MyVm
ressemble à un objet complexe, lu par le formateur à partir du corps, de sorte que vous disposez de deux méthodes identiques en termes de données de route (car aucun d’eux n’a aucun paramètre de la route) - ce qui empêche le répartiteur (IHttpActionSelector
) de correspondre à la un approprié.
Vous devez les différencier par un paramètre de chaîne de requête ou un paramètre de route pour résoudre les ambiguïtés.
Après de nombreuses recherches sur le Web et la recherche de la forme de carte de routage la mieux adaptée Si nous avons 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’appliquant à la fois au mappage du nom de l’action et à la convention http de base (GET, POST, PUT, DELETE)
Sans utiliser d'actions, les options seraient les suivantes:
déplacez l’une des méthodes sur un autre contrôleur afin qu’elles ne s’entrechoquent pas.
utilisez juste une méthode qui prend le paramètre, et si c'est null, appelez l'autre méthode à partir de votre code.
Il est possible que vos méthodes Web soient résolues à la même adresse URL. Regardez le 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.
J'ai constaté que lorsque j'ai deux méthodes Get, une sans paramètre et l'autre avec un type complexe en tant que paramètre, j'ai la même erreur. J'ai résolu ce problème en ajoutant un paramètre factice de type int, nommé Id, en tant que premier paramètre, suivi de mon paramètre de type complexe. J'ai ensuite ajouté le paramètre de type complexe au modèle de route. Ce qui suit a fonctionné pour moi.
D'abord obtenir:
public IEnumerable<SearchItem> Get()
{
...
}
Deuxième get:
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 }
);
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
Veuillez vérifier que vous avez deux méthodes qui portent le même nom et les mêmes paramètres.
Si c'est le cas, supprimez n'importe quelle méthode et essayez.
Cela est possible en raison de l’utilisation du contrôleur MVC au lieu du contrôleur API Web . Vérifiez l’espace de noms dans le contrôleur API Web:
using System.Net;
using System.Net.Http;
using System.Web.Http;
Si les espaces de noms sont comme suit, alors il est donné l'erreur ci-dessus dans l'appel de la méthode du contrôleur API Web
using System.Web;
using System.Web.Mvc;
Je suis tombé sur ce problème en essayant d’augmenter mes contrôleurs WebAPI avec des actions supplémentaires.
Suppose que tu aurais
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 "factices" à mes actions supplémentaires. J'ai donc examiné les actions par défaut et en suis arrivé à:
[ActionName("builtin")]
public IEnumerable<string> Get()
{
return this.Repository.GetAll();
}
pour la première méthode en combinaison avec la liaison "double":
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, vous pouvez apparemment toujours configurer une action par défaut nous permettant de séparer le routage des appels Web "normaux" et des appels à l'action supplémentaire.
Ceci est la réponse pour tous ceux qui savent que tout est correct et qui a vérifié 50 fois .....
Assurez-vous que vous ne regardez pas à plusieurs reprises RouteConfig.cs
.
Le fichier que vous souhaitez modifier s'appelle WebApiConfig.cs
En outre, il devrait probablement ressembler à ceci:
using System.Web.Http;
namespace My.Epic.Website
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
// api/Country/WithStates
config.Routes.MapHttpRoute(
name: "ControllerAndActionOnly",
routeTemplate: "api/{controller}/{action}",
defaults: new { },
constraints: new { action = @"^[a-zA-Z]+([\s][a-zA-Z]+)*$" });
config.Routes.MapHttpRoute(
name: "DefaultActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
J'aurais pu me sauver environ 3 heures.
Dans mon cas, tout allait bien
1) Web Config a été configuré correctement 2) Le préfixe de route et les attributs de route étaient appropriés
J'avais toujours l'erreur. Dans mon cas, l'attribut "Route" (en appuyant sur F12) pointait sur System.Web.MVc mais pas sur System.Web.Http, ce qui était à l'origine du problème.
Vous pouvez ajouter [Route("api/[controller]/[action]")]
à votre classe de contrôleur.
[Route("api/[controller]/[action]")]
[ApiController]
public class MySuperController : ControllerBase
{
...
}
Par exemple => TestController
[HttpGet]
public string TestMethod(int arg0)
{
return "";
}
[HttpGet]
public string TestMethod2(string arg0)
{
return "";
}
[HttpGet]
public string TestMethod3(int arg0,string arg1)
{
return "";
}
Si vous ne pouvez modifier que le fichier WebApiConfig.cs.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/",
defaults: null
);
C'est tout :)
Assurez-vous de ne PAS décorer vos méthodes de contrôleur pour les actions par défaut GET | PUT | POST | DELETE avec l'attribut [HttpPost/Put/Get/Get]. J'avais ajouté cet attribut à l'action de mon contrôleur Vanilla Post et cela provoquait un 404.
J'espère que cela aidera quelqu'un car cela peut être très frustrant et freiner le progrès.
Je sais que la question est ancienne, mais parfois, lorsque vous utilisez des ressources de service comme AngularJS pour vous connecter à WebAPI, assurez-vous que vous utilisez le bon chemin, sinon cette erreur se produit.
Avez-vous essayé comme:
[HttpGet("Summary")]
public HttpResponseMessage Summary(MyVm vm)
{
return null;
}
[HttpGet("FullDetails")]
public HttpResponseMessage FullDetails()
{
return null;
}