WebAPI Delete ne fonctionne pas - Méthode 405 non autorisée

120

J'apprécie toute aide à ce sujet car le site est censé être mis en ligne ce soir!

J'ai un contrôleur d'API Web avec une méthode Delete. La méthode s'exécute correctement sur ma machine locale exécutant IIS Express (Windows 8), mais dès que je l'ai déployée sur le serveur IIS en direct (Windows Server 2008 R2), elle a cessé de fonctionner et renvoie le message d'erreur suivant:

Erreur HTTP 405.0 - Méthode non autorisée La page que vous recherchez ne peut pas être affichée car une méthode non valide (verbe HTTP) est utilisée

J'ai cherché sur le Web des solutions et j'en ai implémenté les plus raisonnables. Ma configuration Web a les paramètres suivants:

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
<handlers>
    <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" />
</handlers>
</system.webServer>

J'ai également essayé de modifier les mappages de gestionnaires et le filtrage des demandes dans IIS en vain. Veuillez noter que les règles de création WebDAV dans IIS semblent être désactivées.

Toutes les idées seront grandement appréciées Merci.

Chris
la source

Réponses:

199

J'ai finalement trouvé la solution! Si vous rencontrez le même problème, ajoutez ce qui suit à votre web.config

<system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/> <!-- ADD THIS -->
    </modules>
    ... rest of settings here

J'espère que ça aide

Chris
la source
2
J'ai également dû ajouter une suppression dans la section des gestionnaires selon stackoverflow.com/a/6698096/254156
rrrr
3
A également travaillé ici. Mais quelqu'un peut-il m'expliquer la relation avec WebDAVModule?
Boas Enkler
11
pour ceux qui ne font que copier-coller: runAllManagedModulesForAllRequests = "true" n'est pas vraiment nécessaire et peut en fait casser d'autres choses.
Zar Shardan
Certains autres articles Web suggéreront de supprimer le module à l'aide de la section Modules IIS, cela le désactive mais cela pose toujours ce problème / un problème similaire, c'est la méthode la plus fiable
Anthony Main
4
@ZarShardan (et autres) FYI: Si vous supprimez l'attribut runAllManagedModulesForAllRequests = "true", vous devrez également ajouter <remove name = "WebDAV" /> sous le nœud <handlers> également.
Aaron
65

Dans certains cas, le supprimer uniquement des modules peut produire l'erreur suivante:

500.21 Le gestionnaire "WebDAV" a un mauvais module "WebDAVModule" dans sa liste de modules

Module: Notification Web Core IIS: ExecuteRequestHandler "

une solution a été suggérée ici . Il faut également le supprimer des gestionnaires.

<system.webServer>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
    <handlers>
        <remove name="WebDAV" />
    </handlers>
</system.webServer>
Aleha
la source
1
cela fonctionne pour moi, mais quelqu'un peut-il nous éclairer sur ce qu'est réellement WebDAV?
Nazrul Muhaimin
31

Dans mon cas, aucune des solutions ci-dessus ne fonctionnait. C'était parce que j'avais changé le nom du paramètre dans ma Deleteméthode.

j'ai eu

public void Delete(string Questionid)

au lieu de

public void Delete(string id)

J'ai besoin d'utiliser le idnom car c'est le nom qui est déclaré dans mon WebApiConfigfichier. Notez le idnom dans les troisième et quatrième lignes:

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

J'ai eu cette solution d' ici .

Hugo Nava Kopp
la source
15

Le DELETEverbe Javascript pour HTTP doit être comme ceci:

$.ajax({
    **url: "/api/SomeController/" + id,**
    type: "DELETE",
    dataType: "json",
    success: function(data, statusText) {
        alert(data);
    },
    error: function(request, textStatus, error) {
        alert(error);
        debugger;
    }
});

N'utilisez pas quelque chose comme ceci:

...
data: {id:id}
...

comme lorsque vous utilisez la POSTméthode.

Pavel Kharibin
la source
1
Salut @ Pavel, c'est correct si vous utilisez effectivement une implémentation entièrement RESTful. Malheureusement, tout le monde ne le fait pas et il est assez courant de voir des développeurs utiliser POST au lieu de DELETE, etc. Merci d'avoir clarifié cela.
Chris
5

Après avoir essayé presque toutes les solutions ici, cela a fonctionné pour moi. Ajoutez ceci dans votre fichier de configuration d'API

<system.webServer>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <modules>
        <remove name="WebDAVModule" />
    </modules>
</system.webServer>
Nithin Chandran
la source
J'ai essayé beaucoup de choses, cela a fonctionné. .NET version 4.6.1 - Merci.
Ketan le
4

Si vous utilisez IIS 7.0 ou une version ultérieure. Ce problème est principalement lié au module d'extension WebDAV sur le serveur IIS. cela s'est produit lors de l'utilisation de l'action Publier OU supprimer.

Veuillez essayer le paramètre ci-dessous dans la configuration Web

<system.webServer>
   <modules>
       <remove name="WebDAVModule" />
   </modules>
   <handlers>
     <remove name="WebDAV" />
   </handlers>
</system.webServer>
Abhishek B.
la source
3

J'ai également eu le même problème, j'appelle WebAPi et j'obtiens cette erreur. L'ajout de la configuration suivante dans web.config pour les services a résolu mon problème

    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/> <!-- add this -->
    </modules>

dans le fichier web.config a résolu mon problème. Voici comment j'appelais du côté client

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(environment.ServiceUrl);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    HttpResponseMessage response = client.DeleteAsync("api/Producer/" + _nopProducerId).Result;
    if (response.IsSuccessStatusCode)
    {
        string strResult = response.Content.ReadAsAsync<string>().Result;
    }
}
Aamir
la source
2

Accédez au fichier applicationHost.config (généralement sous C: \ Windows \ System32 \ inetsrv \ config) et commentez la ligne suivante dans applicationHost.config

1) Sous <gestionnaires>:

<add name="WebDAV" path="*" verb="PROPFIND,PROPPATCH,MKCOL,PUT,COPY,DELETE,MOVE,LOCK,UNLOCK" modules="WebDAVModule" resourceType="Unspecified" requireAccess="None" />

2) Mettez également en commentaire le module suivant référencé par le gestionnaire ci-dessus sous <modules>

<add name="WebDAVModule" />
Arviman
la source
Ou utilisez l'autre réponse stackoverflow.com/a/47907578/1754743 pour SUPPRIMER ces gestionnaires dans votre propre web.config, si vous ne voulez pas (ou ne pouvez pas) modifier le fichier de configuration à l'échelle de la machine
Ekus
2

Dans mon cas, j'ai manqué d'ajouter {id}à la [Route("")]et j'ai eu la même erreur. L'ajout de cela a résolu le problème pour moi:[Route("{id}")]

Reza
la source
Tant d'heures de temps perdu, et si ce n'était pas pour vous, je ne pourrais toujours pas résoudre ce problème ... Je me demande pourquoi il ne renvoie pas 404: @
deadManN
1

J'ai eu la méthode d'erreur 405 non autorisée parce que j'avais omis de rendre publique la méthode Delete sur le contrôleur WebApi.

Il m'a fallu beaucoup de temps pour trouver cela (trop longtemps!) Parce que je m'attendais à une erreur Not Found dans ce cas, donc je supposais à tort que ma méthode Delete était refusée.

La raison de Not Allowed plutôt que Not Found est que j'avais également une méthode Get pour la même route (ce qui sera le cas normal lors de l'implémentation de REST). La fonction publique Get correspond au routage, puis est refusée en raison de la mauvaise méthode http.

Une simple erreur que je connais mais cela peut faire gagner du temps à quelqu'un d'autre.

Paul D
la source
1

Juste pour ajouter. Si c'est votre config

config.Routes.MapHttpRoute (
            nom: "DefaultApi",
            routeTemplate: "api / {controller} / {id}",
            par défaut: new {id = RouteParameter.Optional}

s'il vous plaît continuez à faire comme Hugo l'a dit, et ne définissez pas l'attribut Route sur la méthode get du contrôleur, cela a posé un problème dans mon cas.

user6247020
la source
0

J'ai eu le même problème mais pour PUT - aucune des autres suggestions n'a fonctionné pour moi.

Cependant, j'utilisais intplutôt que la valeur stringpar défaut pour l'ID. l'ajout {id:int}de l'itinéraire a résolu mon problème.

    [Route("api/Project/{id:int}")]
    public async Task<IHttpActionResult> Put(int id, [FromBody]EditProjectCommand value)
    {
       ...
    }
Hath
la source
0

Nous avons dû ajouter des en-têtes personnalisés à notre web.config car notre requête avait plusieurs en-têtes qui confondaient la réponse de l'API.

<httpProtocol>
    <customHeaders>
        <remove name="Access-Control-Allow-Methods" />
        <remove name="Access-Control-Allow-Origin" />
        <remove name="Access-Control-Allow-Headers" />
    </customHeaders>
</httpProtocol>
Zadok
la source
-1

L'attribut [HttpPost] en haut de la méthode Delete a résolu ce problème pour moi:

[HttpPost]
public void Delete(int Id)
{
  //Delete logic
}
Andriy Gubal
la source
Cela pourrait être une raison pour laquelle cela fonctionne pour vous. J'étais sur une version antérieure, vers début 2013, donc pas mal de choses ont été corrigées depuis. Heureux de savoir que cela fonctionne pour vous.
Chris
4
Ce n'est pas une bonne réponse pour être honnête. Les personnes dont le problème a été résolu en utilisant ceci utilisent POST au lieu de DELETE, donc cela ne pouvait pas et ne devrait pas fonctionner
Alexander Derck
Je crois que c'est parce que vous utilisez data(c'est-à-dire le corps de la requête) au lieu de params(c'est-à-dire l'url de la requête) côté client.
Thomas Sauvajon
Je suis d'accord avec Alexander Derck, c'est un kludge plutôt qu'une solution.
Basem Sayej