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

92

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 Release Candidate et je vois maintenant des erreurs sur des appels comme celui-ci:

La ressource demandée ne prend pas en charge 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é.)

Josh Schultz
la source

Réponses:

107

Si vous n'avez configuré aucun HttpMethod sur votre action dans le contrôleur, il est supposé être uniquement HttpPost dans RC. En version bêta, il est supposé prendre en charge toutes les méthodes - GET, PUT, POST et Delete. Il s'agit d'un petit changement de bêta à RC. Vous pouvez facilement décoder plus d'une méthode http sur votre action avec [AcceptVerbs ("GET", "POST")].

dinesh ravva
la source
vient de rencontrer cela, merci pour le correctif, mais curieux, pourquoi dois-je faire cela avec mes méthodes personnalisées, mais pas la méthode par défaut "Get"? J'ai une méthode Get qui a été créée par le modèle pour le contrôleur, mais elle n'est pas décorée. est-ce juste par convention à cause du nom Get?
SelAromDotNet
3
@Josh: Oui! Lorsque le nom de la méthode d'action commence par "Get ...", vous n'avez pas à la marquer comme méthode GET. En savoir plus ici: asp.net/web-api/overview/web-api-routing-and-actions/…
Jenny O'Reilly
J'ai fait comme suggéré dans la réponse, mais maintenant mes deux appels, Get et Post, sont redirigés vers Get Action. Une aide s'il vous plaît?
Syed Ali Taqi
54

Toutes les informations ci-dessus sont correctes, je tiens également à souligner que l' [AcceptVerbs()]annotation existe à la fois 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 d'API Web.

Eric
la source
@Eric. Génial, c'était la raison pour laquelle cela ne fonctionnait pas pour moi. J'avais le verbe sur mon action mais il était référencé via Web.Mvc donc ne fonctionnait pas.
dreza
Génial, vous avez sauvé ma journée
Hossein Narimani Rad
Merci beaucoup, car System.Web.Mvc n'était pas bon pour moi.
Burak Karakuş
34

Bien que ce ne soit pas une réponse à l'OP, j'ai eu exactement la même erreur d'une cause racine 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 mal nommé qui a amené WebAPI à acheminer la demande de manière inattendue. J'ai les méthodes suivantes dans mon ProgrammesController:

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

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

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

La solution était donc simple:

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

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

Carl Sharman
la source
1
Si quelqu'un utilise le routage par URL, essayez de faire comme [Route ("{programmeId = programmeId: int}")]
sree
1
C'était tout pour moi. WebApiConfig -> MapHttpRoutes avait -> routeTemplate: "api / {controller} / {id}", donc un paramètre de 'id' devait être utilisé.
HockeyJ
1
votre réponse m'a signalé mon problème qui était un peu différent. J'ai changé le nom d'un paramètre [FromUri] pour la méthode et je ne l'ai pas mis à jour côté client
Matus
22

Si vous décorez votre méthode avec HttpGet, ajoutez ce qui suit usingen haut du contrôleur:

using System.Web.Http;

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

Sohail xIN3N
la source
5
C'est vrai, et ridiculement .NET ne montre pas clairement le message.
Teoman shipahi
15

C'est certainement un changement de Beta à 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 mélanger des actions basées sur des verbes (c'est-à-dire "GetSomething", "PostSomething") avec des actions non basées sur des verbes. Si vous essayez d'utiliser les attributs ci-dessus, cela provoquera un conflit avec toute action basée sur des verbes dans votre contrôleur. Une façon d'obtenir un montant serait de définir des routes séparées 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 l'API Web auront un meilleur support pour ce scénario. Un problème est actuellement enregistré sur le projet codeplex aspnetwebstack, http://aspnetwebstack.codeplex.com/workitem/184 . Si c'est quelque chose que vous aimeriez voir, veuillez voter sur la question.

Jérémie
la source
8

Avoir la même configuration que OP. Un contrôleur avec de nombreuses 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" };
}
Shaakir
la source
6

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

Vern D.
la source
3

Remplacez 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 }
                          );
Kazem Maleki
la source
1

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

Pierrick Martellière
la source
0

Mon problème était aussi simple que d'avoir une référence nulle qui n'apparaissait pas dans le message retourné, j'ai dû déboguer mon API pour la voir.

Ninos
la source