Metodo 405 non consentito API Web


88

Questo errore è molto comune e ho provato tutte le soluzioni e nessuna di esse ha funzionato. Ho disabilitato la pubblicazione WebDAV nel pannello di controllo e l'ho aggiunto al mio file di configurazione web:

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

L'errore persiste ancora. Questo è il controller:

   static readonly IProductRepository repository = new ProductRepository();

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

Implementazione del metodo:

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

Ed è qui che viene lanciata l'eccezione:

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

Eventuali suggerimenti?

Risposte:


61

Stai POSTANDO dal cliente:

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

non PUTing.

Il tuo metodo API Web accetta solo richieste PUT.

Così:

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

L'errore "HttpClient" non contiene una definizione per "PostAsJsonAsync" viene generato quando viene provato il codice.
agileDev

61

Ho avuto la stessa eccezione. Il mio problema era che avevo usato:

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

DOVREBBE ESSERE

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

18

Ho provato molte cose per far funzionare il metodo DELETE (stavo ottenendo il metodo 405 non consentito api web), e alla fine ho aggiunto [Route ("api / scan / {id}")] al mio controller e funzionava bene. spero che questo post aiuti qualcuno.

     // 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);
    }

Per qualche motivo il mio non funzionava solo per l'eliminazione, per la creazione e l'aggiornamento ha funzionato bene. Bene, ho appena aggiunto [HttpPost] e ha funzionato. Ma grazie, mi hai messo sulla strada giusta e mi è costato solo 5 minuti ora :)
Rubenisme

1
Perché non stai semplicemente aggiungendo l'attributo [HttpDelete]?
johnny 5

14

Il mio problema si è rivelato essere il routing degli attributi in WebAPI. Ho creato un percorso personalizzato e l'ho trattato come un GET invece di WebAPI scoprendo che era un POST

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

Sapevo che doveva essere qualcosa di stupido (che consuma l'intera giornata)


Questo mi ha salvato la giornata!
Phate01

6

Chrome spesso tenta di fare una OPTIONSchiamata prima di fare un post. Lo fa per assicurarsi che le intestazioni CORS siano in ordine. Può essere problematico se non gestisci la OPTIONSchiamata nel tuo controller API.

public void Options() { }

6

Questo errore può verificarsi anche quando si tenta di connettersi a http mentre il server è su https.

È stato un po 'confuso perché le mie richieste di ricezione erano OK, il problema era presente solo con le richieste successive.


4

Stavo ottenendo il 405 sulla mia chiamata GET e il problema si è scoperto che ho chiamato il parametro nel metodo lato server GET Get(int formId)e avevo bisogno di cambiare il percorso o rinominarlo Get(int id).


4

Puoi anche ottenere l'errore 405 se supponi che il tuo metodo si aspetti un parametro e non lo stai passando.

NON funziona (errore 405)

Visualizzazione HTML / Javascript

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

API Web:

public HttpResponseMessage GetNews(int id)

Quindi, se la firma del metodo è come quella sopra, devi fare:

Visualizzazione HTML / Javascript

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

Mi sembra di incorrere in errori 405 per vari motivi, si riducono tutti al fatto che si tenta di HIT la firma del metodo e un problema di parametro o un problema di denominazione di convenzione o un problema di attributo ecc ...
Tom Stickel,

4

Sono in ritardo a questa festa, ma poiché nella maggior parte dei casi nulla era fattibile o funzionante, ecco come è stato finalmente risolto per me.

Sul server su cui era ospitato il sito / servizio, era necessaria una funzionalità! ATTIVAZIONE HTTP !!!

Server Manager> Gestisci> Aggiungi ruoli e funzionalità> avanti avanti avanti fino ad arrivare a Funzionalità> In .NET (ogni versione) spuntare Attivazione HTTP. Nota anche che ce n'è uno nascosto in> net> Servizi WCF.

Questo poi ha funzionato immediatamente! Questo mi stava sciogliendo il cervello


4

Se hai un percorso come

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

È necessario utilizzare lo stesso identico nome di parametro nel metodo, ad es

public ReactorModel GetReactor(reactorId)
{
 ...
}

Se non si passa esattamente lo stesso parametro, è possibile che venga visualizzato l'errore "metodo 405 non consentito" perché il percorso non corrisponderà alla richiesta e WebApi raggiungerà un metodo controller diverso con un metodo HTTP consentito diverso.


Anche questa non è una risposta!
Divyang Desai

@Div "Metodo 405 non consentito" può essere mostrato nel caso che ho condiviso perché il metodo non catturerà la chiamata api poiché l'impostazione del percorso non è valida. La chiamata api può quindi colpire un altro metodo non intenzionale che potrebbe avere un'azione HTTP diversa consentita. Sì, sono d'accordo che questa risposta potrebbe non essere pertinente al 100% per la domanda effettiva, tuttavia il titolo della domanda di Xardas non è molto specifico e credo che molte persone che approdano qui in cerca di risposte alla domanda come indicato dal titolo potrebbero trovo utile questa risposta.
roylac


3

Questo non risponde alla tua domanda specifica, ma quando ho avuto lo stesso problema sono finito qui e ho pensato che più persone avrebbero potuto fare lo stesso.

Il problema che avevo era che avevo dichiarato in modo indelebile il mio metodo Get come statico . Mi sono perso un'intera mattinata e non ha causato avvertimenti da attributi o simili.

Errato:

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

Corretta:

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

2

[HttpPost] non è necessario!

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

1
Sì, il modo in cui lo fai è corretto in quanto non hai bisogno di un [HttpPost] esplicito, tuttavia ci sono alcune persone che non seguono le convenzioni (yikes) e quindi qualcosa come [Route ("MyMethodSaver"] stringa pubblica MyMethodtoSave (int? id) -> che avrebbe bisogno di un [HttpPost] e poi funzionerebbe
Tom Stickel

2

NON ho potuto risolvere questo problema. Avevo CORS abilitato e funzionava fino a quando il POST restituiva void (ASP.NET 4.0 - WEBAPI 1). Quando ho provato a restituire un HttpResponseMessage, ho iniziato a ricevere la risposta HTTP 405.

Sulla base della risposta di Llad sopra, ho dato un'occhiata ai miei riferimenti.

Avevo l'attributo [System.Web.Mvc.HttpPost] elencato sopra il mio metodo POST.

L'ho modificato per utilizzare:

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

Questo ha risolto i miei guai. Spero che questo aiuti qualcun'altro.

Per motivi di completezza, ho avuto quanto segue nel mio 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>

Questo avrà il metodo chiamato sulla richiesta pre-volo OPTIONS (così come su POST), a quel punto jsonè probabile nullpoiché le richieste pre-volo di solito non hanno payload, oppure eseguirai l'azione post due volte.
glennsl

1

Abbiamo avuto un problema simile. Stavamo cercando di OTTENERE da:

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

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

    }

}

Quindi lo faremmo .GET("/api/car")e questo lancerebbe un file 405 error.


La correzione:

Il CarController.csfile era nella directory, /api/carquindi quando stavamo richiedendo questo endpoint api, IIS restituiva un errore perché sembrava che stessimo tentando di accedere a una directory virtuale a cui non era consentito.

Opzione 1: cambia / rinomina la directory in cui si trova il controller
Opzione 2: cambia il prefisso della rotta in qualcosa che non corrisponde alla directory virtuale.


1

Nel mio caso avevo una cartella fisica nel progetto con lo stesso nome della rotta WebAPI (es. Sandbox) e solo la richiesta POST è stata intercettata dal gestore dei file statici in IIS (ovviamente).

Ottenere un errore 405 fuorviante invece del 404 più atteso, è stato il motivo per cui mi ci è voluto molto tempo per la risoluzione dei problemi.

Non è facile cadere in questo, ma possibile. Spero che aiuti qualcuno.


1

Da parte mia il mio gestore POST era di questa forma:

[HttpPost("{routeParam}")]
public async Task<ActionResult> PostActuality ([FromRoute] int routeParam, [FromBody] PostData data)

Ho capito che dovevo scambiare gli argomenti , vale a dire prima i dati del corpo e poi il parametro del percorso, come questo:

[HttpPost("{routeParam}")]
public async Task<ActionResult> PostActuality ([FromBody] PostData data, [FromRoute] int routeParam)

0

archiviare il file .csproj del progetto e modificare

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

all'URL del tuo sito web in questo modo

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

0

Un altro possibile problema che causa lo stesso comportamento sono i parametri predefiniti nel routing. Nel mio caso il controller è stato individuato e istanziato correttamente, ma il POST è stato bloccato a causa Getdell'azione predefinita specificata:

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

0

Stavo avendo esattamente lo stesso problema. Ho cercato per due ore cosa non andava senza fortuna fino a quando mi sono reso conto che il mio POSTmetodo era privateinvece di public.

Divertente ora vedere che il messaggio di errore è un po 'generico. Spero che sia d'aiuto!


0

Assicurati che il tuo controller erediti dalla Controllerclasse.

Potrebbe anche essere più folle che le cose funzionino localmente anche senza.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.