web-dev-qa-db-fra.com

Web API - 405 - La ressource demandée ne prend pas en charge la méthode http 'PUT'

J'ai un projet d'API Web et je ne parviens pas à activer les requêtes "PUT/Patch".

La réponse que je reçois du violoneux est la suivante:


HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Allow: GET,POST,DELETE
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcUHJvamVjdHNcZG90TmV0XFdlYkFQSVxBZFNlcnZpY2VcQWRTZXJ2aWNlXGFwaVxpbXByZXNzaW9uXDE1?=
X-Powered-By: ASP.NET
Date: Tue, 06 May 2014 14:10:35 GMT
Content-Length: 72

{"message":"The requested resource does not support http method 'PUT'."}

Sur la base de la réponse ci-dessus, les verbes "PUT" ne sont pas acceptés. Cependant, je suis incapable de déterminer où le gestionnaire associé est configuré.

La méthode de classe "Put" est déclarée comme suit:

[HttpPatch]
[HttpPut]
public HttpResponseMessage Put(Int32 aID, [FromBody] ImpressionModel impressionModel)
{
     bla, bla, bla, bla
}

J'ai lu et mis en œuvre les modifications expliquées dans les discussions suivantes: - API Web Asp.NET - 405 - Le verbe HTTP utilisé pour accéder à cette page n'est pas autorisé - Comment définir des mappages de gestionnaires - http://www.asp.net/web-api/overview/testing-and-debugging/troubleshooting-http-405-errors-after-publishing-web-api-applications

Rien n'a fonctionné car je reçois toujours une réponse 405 lorsque j'essaie d'émettre une commande "PUT" contre mon projet d'API Web.

J'ai même commenté tous les "gestionnaires" du fichier ApplicationsHost.config.

Travailler avec VS2012 Premium et IIS Express (je suppose que c'est la version 8). J'ai aussi essayé le serveur de développement VS mais cela m'a aussi donné le même résultat.

Je suis à court d'idées. Toute aide serait appréciée.

Merci Lee

18
LeeVDuhl

Utilisez-vous un routage d'attribut?

Cette erreur mystique était un problème de route attributs. Ceci est activé dans votre WebAPIConfig en tant que:

 config.MapHttpAttributeRoutes(); 

Il s’avère que les contrôleurs Web Api "ne peuvent pas héberger une combinaison de méthodes d’action basées sur les verbes et de routage de nom d’action traditionnel"; https://aspnetwebstack.codeplex.com/workitem/184

en un mot: J'avais besoin de marquer toutes mes actions dans mon contrôleur API avec l'attribut [Route], sinon l'action est "cachée" (405) lorsque vous essayez de la localiser via un routage traditionnel.

Contrôleur d'API:

[RoutePrefix("api/quotes")]
public class QuotesController : ApiController
{
    ...

    // POST api/Quote
    [ResponseType(typeof(Quote))]
    [Route]
    public IHttpActionResult PostQuote(Quote quote)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Quotes.Add(quote);
        db.SaveChanges();

        return CreatedAtRoute("", new { id = quote.QuoteId }, quote);
    }

note: ma route n'a pas de nom, le nom CreatedAtRoute () est simplement une chaîne vide.

WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

        // Web API routes
        config.MapHttpAttributeRoutes();

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

    }
}

j'espère que cela t'aides 

22
proggrock

J'ai eu exactement le même problème que vous et j'ai essayé tout ce que vous avez essayé, mais parfois, la solution est si triviale et sous votre nez que vous ne vous attendez pas à cela et continuez à chercher des raisons plus compliquées. Assurez-vous que dans l'URL que vous appelez pour tester vos méthodes Web, les noms de paramètres correspondent aux noms figurant dans la déclaration de votre méthode de contrôleur. Mon problème 405 a été résolu simplement en procédant comme suit (j'utilisais des paramètres de requête):

Mes clientsController:

...

[HttpPut]
public string PutClient(string username = "", string phone= ""){...}

Sur mon WebApiConfig:

// Web API routes
config.MapHttpAttributeRoutes();

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

Et le chemin utilisé pour tester la méthode doit être comme suit: (utilisez Postman ou similaire, pour appliquer la méthode Web correcte)

http://localhost:49216/api/clients?username=Kurt&phone=443332211

Sinon, vous obtiendrez un 405 pour cette méthode http dans ce contrôleur. Je n'ai pas eu besoin de changer le web.config du tout (pas besoin de supprimer webdav, etc.). Vérifiez this pour la source dans la documentation: 

Par exemple, considérons l'action suivante:

public void Get (int id) 

Le paramètre id est lié à l'URI. Donc, cette action ne peut correspondre qu'à un URI contenant une valeur pour "id", soit dans le dictionnaire de route ou dans la chaîne de requête.

Les paramètres facultatifs sont une exception, car ils sont facultatifs. Pour un paramètre optionnel, c'est OK si la liaison ne peut pas obtenir la valeur de l'URI.

8
kurt

Cela m'est arrivé lorsque j'ai changé le premier nom de paramètre de la méthode PUT

public void Put(int code, [FromBody]Lead lead)

CA devrait etre:

public void Put(int id, [FromBody]Lead lead)

Et voici comment cela s'appelle:

$.ajax({
    type: "PUT",
    data: json,
    url: "../api/leadsapi/123",
    contentType: "application/json; charset=utf-8"
});
2
Daniel Cardenas

Cette réponse a résolu le problème pour moi. J'ai dû ajouter l'attribut Route et le problème a été résolu. 

    [HttpPut]
    [Route("")]
    public HttpResponseMessage MyMethod()
1
Dave Storm

avait le même problème, je devais faire 3 choses pour résoudre ceci:

  1. désactiver Webdav dans <modules> et <handlers>
  2. Assurez-vous que HttpPut provient de System.Web.Http et non de System.Web.Mvc lorsque vous utilisez WebAPI.
  3. active ExtensionlessUrlHandler comme ceci

<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />

<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />

<remove name="ExtensionlessUrlHandler-Integrated-4.0" />

<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />

<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

J'espère que cela pourra aider certains d'entre vous à résoudre ce vilain problème ...

1
Ben Croughs

C'est également le message d'erreur renvoyé si vous oubliez de rendre publique la méthode Put () sur votre contrôleur d'API. Ce qui est évident avec le recul, mais m'a causé une bonne dizaine de minutes de casse-tête.

1
Dylan Beattie

Ajoutez la section suivante sous la section Handler dans web.config:

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

Par exemple:

<handlers>
    <remove name="WebDAV" />
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <remove name="TRACEVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
0
Sulabh Singla

Peut-être qu'il est tard maintenant, mais quelqu'un peut l'utiliser.

Je voulais utiliser la requête PUT et je viens d'envoyer un objet sous forme de chaîne à une API Web et la méthode In put uniquement accepter cet objet.

JQUERY

let musterija = {
            Name: name,
            Email: email,
            Password: password,
            Username: logUser.Username,
            Lastname: lastname,
            GenderString: gender,
            Jmbg: identification,
            PhoneNumber: phone,
        };

        $.ajax({
            method: "PUT",
            url: "/api/Musterija",
            data: JSON.stringify(musterija),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function () {
                alert("Entity updated");
                EmptyAllInputs();
                $('#divprofile').show();
                $('#divupdate').hide();
            },
            error: function (msg) {
                alert("Fail - " + msg.responseText);
            }
        });

API WEB

    [HttpPut]
    public HttpResponseMessage PutMusterija(Musterija m)
0
Serlok

Vous devez le configurer dans la configuration de votre serveur Web. Cela dépend du type de serveur Web, où vous pouvez le faire. Par exemple, avec IIS, vous pouvez utiliser un fichier web.config pour le faire dans la racine de votre document. Par requêtes croisées, vous devez ajouter des en-têtes CORS à la réponse pour autoriser les origines, les méthodes, etc.

note: Vous pouvez probablement faire quelque chose à ce sujet avec le framework ASP.NET également, mais je pense que c'est différent.

0
inf3rno