web-dev-qa-db-fra.com

ASP.NET Web Api: la ressource demandée ne prend pas en charge la méthode http 'GET'

J'ai l'action suivante sur un ApiController:

public string Something()
{
    return "value";
}

Et j'ai configuré mes itinéraires comme suit:

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

Dans la version bêta, cela fonctionnait très bien, mais je viens de mettre à jour la dernière version candidate et je vois maintenant des erreurs sur des appels comme celui-ci:

La ressource demandée ne supporte pas la méthode http 'GET'.

Pourquoi ça ne marche plus?

(Je suppose que je pourrais me débarrasser de {action} et créer une tonne de contrôleurs, mais cela semble compliqué.)

87
Josh Schultz

Si vous n'avez pas configuré de méthode HttpMethod sur votre action dans le contrôleur, il est supposé qu'il ne s'agit que de HttpPost dans RC. Dans la version bêta, il est supposé prendre en charge toutes les méthodes - GET, PUT, POST et Delete. Ceci est une petite modification de la version bêta à la méthode RC. Vous pouvez facilement décoder plus d'une httpmethod sur votre action avec [AcceptVerbs ("GET", "POST")].

107
dinesh ravva

Toutes les informations ci-dessus sont correctes. J'aimerais également souligner que l'annotation [AcceptVerbs()] existe dans les espaces de noms System.Web.Mvc et System.Web.Http.

Vous souhaitez utiliser System.Web.Http s'il s'agit d'un contrôleur API Web.

52
Eric

Bien que cela ne soit pas une réponse au PO, j’ai eu exactement la même erreur d’une cause fondamentale complètement différente; donc au cas où cela aiderait quelqu'un d'autre ...

Le problème pour moi était un paramètre de méthode incorrectement nommé qui a amené WebAPI à router la demande de manière inattendue. J'ai les méthodes suivantes dans mes programmesController:

[HttpGet]
public Programme GetProgrammeById(int id)
{
    ...
}

[HttpDelete]
public bool DeleteProgramme(int programmeId)
{
    ...
}

Les demandes DELETE à .../api/programmes/3 n'étaient pas acheminées vers DeleteProgramme comme prévu, mais vers GetProgrammeById, car DeleteProgramme n'avait pas de nom de paramètre id. GetProgrammeById rejetait bien sûr le DELETE car il est marqué comme n'acceptant que les GET.

Donc, la solution était simple:

[HttpDelete]
public bool DeleteProgramme(int id)
{
    ...
}

Et tout va bien. Erreur stupide vraiment mais difficile à déboguer.

33
Carl Sharman

Si vous décorez votre méthode avec HttpGet, ajoutez le using suivant en haut du contrôleur:

using System.Web.Http;

Si vous utilisez System.Web.Mvc, alors ce problème peut se produire.

19
Sohail xIN3N

C'est certainement un changement de la version bêta à la version RC. Dans l'exemple fourni dans la question, vous devez maintenant décorer votre action avec [HttpGet] ou [AcceptVerbs ("GET")].

Cela pose un problème si vous souhaitez combiner des actions basées sur un verbe (par exemple, "GetSomething", "PostSomething") avec des actions non basées sur un verbe. Si vous essayez d'utiliser les attributs ci-dessus, cela provoquera un conflit avec toute action basée sur un verbe dans votre contrôleur. Une façon de résoudre ce problème serait de définir des itinéraires distincts pour chaque verbe et de définir l'action par défaut sur le nom du verbe. Cette approche peut être utilisée pour définir des ressources enfants dans votre API. Par exemple, le code suivant prend en charge: "/ resource/id/children", où id et children sont facultatifs.

        context.Routes.MapHttpRoute(
           name: "Api_Get",
           routeTemplate: "{controller}/{id}/{action}",
           defaults: new { id = RouteParameter.Optional, action = "Get" },
           constraints: new { httpMethod = new HttpMethodConstraint("GET") }
        );

        context.Routes.MapHttpRoute(
           name: "Api_Post",
           routeTemplate: "{controller}/{id}/{action}",
           defaults: new { id = RouteParameter.Optional, action = "Post" },
           constraints: new { httpMethod = new HttpMethodConstraint("POST") }
        );

Espérons que les futures versions de Web API prendront mieux en charge ce scénario. Un problème est actuellement enregistré dans le projet codeplex aspnetwebstack, http://aspnetwebstack.codeplex.com/workitem/184 . Si c'est quelque chose que vous aimeriez voir, veuillez voter sur la question.

14
Jeremy

Même problème que ci-dessus, mais racine très différente. Pour moi, c’était que je touchais un noeud final avec une règle de réécriture https. Le frapper sur http a provoqué l'erreur et a fonctionné comme prévu avec https.

4
Vern D.

Avoir la même configuration que OP. Un contrôleur avec beaucoup d'actions ... moins "salissant" :-)

Dans mon cas, j'ai oublié le "[HttpGet]" lors de l'ajout d'une nouvelle action.

[HttpGet]
public IEnumerable<string> TestApiCall()
{
    return new string[] { "aa", "bb" };
}
4
Shaakir

Remplace le code suivant dans ce chemin

Chemin :

App_Start => WebApiConfig.cs

Code:

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

Je ne sais pas si cela peut être lié au message de l'OP mais il me manquait l'annotation [HttpGet] et c'est ce qui causait l'erreur, comme indiqué par les méthodes @dinesh_ravva sont supposées être HttpPost par défaut.

1

Mon problème était aussi simple que d'avoir une référence null qui n'apparaissait pas dans le message renvoyé, je devais déboguer mon API pour le voir.

0
Ninos