web-dev-qa-db-fra.com

Méthode 405 non autorisée web api

Cette erreur est très courante et j’ai essayé toutes les solutions et aucune d’entre elles n’a fonctionné. J'ai désactivé la publication WebDAV dans le panneau de configuration et ajouté ceci à mon fichier de configuration Web:

  <handlers>
  <remove name="WebDAV"/>
  </handlers>
  <modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule"/>
  </modules>

L'erreur persiste toujours. C'est le contrôleur:

   static readonly IProductRepository repository = new ProductRepository();

    public Product Put(Product p)
    {
        return repository.Add(p);
    }

Mise en œuvre de la méthode:

 public Product Add(Product item)
    {
        if (item == null)
        {
            throw new ArgumentNullException("item");
        }
        item.Id = _nextId++;
        products.Add(item);
        return item;
    }

Et c'est là que l'exception est levée:

client.BaseAddress = new Uri("http://localhost:5106/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));      
var response = await client.PostAsJsonAsync("api/products", product);//405 exception

Aucune suggestion?

74
Xardas

Vous publiez du client:

await client.PostAsJsonAsync("api/products", product);

ne pas mettre. 

Votre méthode API Web accepte uniquement les demandes PUT.

Alors:

await client.PutAsJsonAsync("api/products", product);
48
Darin Dimitrov

J'ai eu la même exception. Mon problème était que j'avais utilisé:

using System.Web.Mvc; // Wrong namespace for HttpGet attribute !!!!!!!!!
[HttpGet]
public string Blah()
{
    return "blah";
}

DEVRAIT ÊTRE

using System.Web.Http; // Correct namespace for HttpGet attribute !!!!!!!!!
[HttpGet]
public string Blah()
{
    return "blah";
}
55
Llad

J'ai essayé beaucoup de choses pour que la méthode DELETE fonctionne (la méthode 405 n'était pas autorisée avec l'API Web), et j'ai finalement ajouté [Route ("api/scan/{id}")] à mon contrôleur et le travail était parfait . J'espère que ce post aidera quelqu'un.

     // DELETE api/Scan/5
    [Route("api/scan/{id}")]
    [ResponseType(typeof(Scan))]
    public IHttpActionResult DeleteScan(int id)
    {
        Scan scan = db.Scans.Find(id);
        if (scan == null)
        {
            return NotFound();
        }

        db.Scans.Remove(scan);
        db.SaveChanges();

        return Ok(scan);
    }
17
user2662006

Mon problème s'est avéré être le routage d'attributs dans WebAPI. J'ai créé un itinéraire personnalisé et il l'a traité comme un GET au lieu de WebAPI, découvrant qu'il s'agissait d'un POST.

    [Route("")]
    [HttpPost] //I added this attribute explicitly, and it worked
    public void Post(ProductModel data)
    {
        ...
    }

Je savais que ça devait être quelque chose d'idiot (ça prend toute la journée)

10
Nexxas

Voici une solution 

<handlers accessPolicy="Read, Script"> <remove name="WebDAV" /> </handlers>

docs.Microsoft.com article de solution

et supprimer WebDAV des modules

<remove name="WebDAVModule" />

Si vous avez un itinéraire comme

[Route("nuclearreactors/{reactorId}")]

Vous devez utiliser exactement le même nom de paramètre dans la méthode, par exemple. 

public ReactorModel GetReactor(reactorId)
{
 ...
}

Si vous ne transmettez pas exactement le même paramètre, vous risquez d'obtenir l'erreur "Méthode 405 non autorisée" car l'itinéraire ne correspondra pas à la demande et WebApi utilisera une méthode de contrôleur différente avec une méthode HTTP autorisée différente.

4
roylac

Je recevais le 405 sur mon appel GET, et le problème est que j'ai nommé le paramètre dans la méthode GET côté serveur Get(int formId) et que je devais modifier l'itinéraire ou le renommer Get(int id).

4
Sako73

Chrome essaie souvent de faire un appel OPTIONS avant de publier un message. Cela permet de s'assurer que les en-têtes CORS sont en ordre. Cela peut être problématique si vous ne gérez pas l'appel OPTIONS dans votre contrôleur d'API.

public void Options() { }
4
Nate Zaugg

Vous pouvez également obtenir l'erreur 405 si, par exemple, votre méthode attend un paramètre et que vous ne le transmettez pas.

Cela ne fonctionne pas (erreur 405)

Vue HTML/Javascript

$.ajax({
         url: '/api/News',
         //.....

Web Api:

public HttpResponseMessage GetNews(int id)

Ainsi, si la signature de la méthode est semblable à celle décrite ci-dessus, vous devez procéder comme suit:

Vue HTML/Javascript

$.ajax({
         url: '/api/News/5',
         //.....
4
Tom Stickel

Je suis en retard pour ce parti mais comme ci-dessus rien n'était viable ni ne fonctionnait dans la plupart des cas, voici comment cela a finalement été résolu pour moi.

Sur le serveur sur lequel le site/service était hébergé, une fonctionnalité était requise! HTTP ACTIVATION !!!

Gestionnaire de serveur> Gérer> Ajouter des rôles et des fonctionnalités> suivant suivant jusqu'à ce que vous accédiez à Fonctions> Sous .NET (chaque version), cochez Activation HTTP . Notez également qu'il y en a un caché sous> net> Services WCF.

Cela a ensuite fonctionné instantanément! Cela fondait mon cerveau

3
Monolithcode

Cette erreur peut également se produire lorsque vous essayez de vous connecter à http alors que le serveur est sur https. 

C'était un peu déroutant parce que mes demandes d'obtention étaient acceptables, le problème n'était présent qu'avec les demandes postérieures. 

3
FrankyHollywood

Je ne pourrais PAS résoudre ceci. CORS était activé et fonctionnait aussi longtemps que POST avait rendu le vide (ASP.NET 4.0 - WEBAPI 1). Lorsque j'ai essayé de renvoyer un HttpResponseMessage, j'ai commencé à recevoir la réponse HTTP 405.

Sur la base de la réponse de Llad ci-dessus, j'ai jeté un coup d'œil à mes propres références. 

J'avais l'attribut [System.Web.Mvc.HttpPost] répertorié ci-dessus ma méthode POST. 

J'ai changé ceci pour utiliser: 

[System.Web.Http.HttpPostAttribute]
[HttpOptions]
public HttpResponseMessage Post(object json)        
{
    ...
    return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
}

Cela a corrigé mes malheurs. J'espère que ça aidera quelqu'un d'autre. 

Par souci d’exhaustivité, j’avais les éléments suivants dans mon Web.config: 

<httpProtocol>
    <customHeaders>
        <clear />
        <add name="Access-Control-Expose-Headers " value="WWW-Authenticate"/>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, PATCH, DELETE" />
        <add name="Access-Control-Allow-Headers" value="accept, authorization, Content-Type" />
        <remove name="X-Powered-By" />
    </customHeaders>
</httpProtocol>
2
Spencer Sullivan

Cela ne répond pas à votre question précise, mais lorsque j’ai eu le même problème, j’ai fini ici et j’ai pensé que plus de gens pourraient faire de même.

Le problème que j’avais, c’est que j’avais déclaré de manière indélébile que ma méthode Get était statique . Cela m'a manqué toute une matinée, et cela n’a provoqué aucun avertissement d’attributs ou similaires.

Incorrect:

public class EchoController : ApiController
{
    public static string Get()
    {
        return string.Empty;
    }
}

Correct:

public class EchoController : ApiController
{
    public string Get()
    {
        return string.Empty;
    }
}
2
Per Stolpe

[HttpPost] est inutile!

[Route("")]
public void Post(ProductModel data)
{
    ...
}
1
user3963793

Un autre problème possible qui entraîne le même comportement concerne les paramètres par défaut du routage. Dans mon cas, le contrôleur a été correctement localisé et instancié, mais le POST a été bloqué en raison de l'action Get par défaut spécifiée:

config.Routes.MapHttpRoute(
    name: "GetAllRoute",
    routeTemplate: "api/{controller}.{ext}"/*,
    defaults: new { action = "Get" }*/ // this was causing the issue
);
0
Eadel

J'avais exactement le même problème. J'ai cherché pendant deux heures ce qui n'allait pas sans succès jusqu'à ce que je réalise que ma méthode POST était private au lieu de public

C'est drôle de voir que ce message d'erreur est générique. J'espère que ça aide!

0
Gonzo345

Nous avons eu un problème similaire. Nous essayions d'obtenir de:

[RoutePrefix("api/car")]
public class CarController: ApiController{

    [HTTPGet]
    [Route("")]
    public virtual async Task<ActionResult> GetAll(){

    }

}

Donc, nous aurions .GET("/api/car") et cela jetterait un 405 error.


Le correctif:

Le fichier CarController.cs se trouvait dans le répertoire /api/car. Ainsi, lorsque nous demandions ce point de terminaison api, IIS renvoyait une erreur car il semblait que nous essayions d'accéder à un répertoire virtuel auquel nous n'étions pas autorisés. 

Option 1: change/renomme le répertoire dans lequel se trouve le contrôleur
Option 2: changez le préfixe de route en un nom ne correspondant pas au répertoire virtuel.

0
Zze

Dans mon cas, le projet contenait un dossier physique portant le même nom que la route WebAPI (par exemple, un bac à sable) et seule la demande POST était interceptée par le gestionnaire de fichiers statiques dans IIS (évidemment).

Obtenir une erreur 405 trompeuse au lieu de la plus attendue 404, était la raison pour laquelle il m'a fallu longtemps pour dépanner.

Pas facile de tomber dedans, mais possible. J'espère que ça aide quelqu'un.

0
Panos Roditakis

archivez votre fichier .csproj de projet et modifiez-le 

<IISUrl>http://localhost:PORT/</IISUrl>

à votre URL de site Web comme ceci

<IISUrl>http://example.com:applicationName/</IISUrl>
0
Ankit