405 Methode nicht erlaubt Web API

87

Dieser Fehler ist sehr häufig und ich habe alle Lösungen ausprobiert und keine davon hat funktioniert. Ich habe die WebDAV-Veröffentlichung in der Systemsteuerung deaktiviert und dies meiner Webkonfigurationsdatei hinzugefügt:

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

Der Fehler bleibt bestehen. Dies ist der Controller:

   static readonly IProductRepository repository = new ProductRepository();

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

Methodenimplementierung:

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

Und hier wird die Ausnahme ausgelöst:

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

Irgendwelche Vorschläge?

Xardas
quelle

Antworten:

61

Sie veröffentlichen vom Client aus:

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

nicht PUTing.

Ihre Web-API-Methode akzeptiert nur PUT-Anforderungen.

So:

await client.PutAsJsonAsync("api/products", product);
Darin Dimitrov
quelle
Fehler 'HttpClient' enthält keine Definition für 'PostAsJsonAsync' wird ausgelöst, wenn Ihr Code ausprobiert wird.
agileDev
60

Ich hatte die gleiche Ausnahme. Mein Problem war, dass ich verwendet hatte:

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

SOLLTE SEIN

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

Ich habe viele Dinge versucht, um die DELETE-Methode zum Laufen zu bringen (ich habe die 405-Methode nicht als Web-API zugelassen), und schließlich habe ich [Route ("api / scan / {id}")] zu meinem Controller hinzugefügt und funktionierte einwandfrei. hoffe, dieser Beitrag hilft jemandem.

     // 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);
    }
user2662006
quelle
Aus irgendeinem Grund funktionierte es nur nicht für das Löschen, zum Erstellen und Aktualisieren funktionierte es einwandfrei. Nun, ich habe gerade [HttpPost] hinzugefügt und es hat funktioniert. Aber danke, du hast mich auf den richtigen Weg gebracht und mich jetzt nur 5 Minuten gekostet :)
Rubenisme
1
Warum fügen Sie nicht einfach das Attribut [HttpDelete] hinzu?
Johnny 5
13

Mein Problem stellte sich als Attribut-Routing in WebAPI heraus. Ich habe eine benutzerdefinierte Route erstellt, die wie ein GET behandelt wurde, anstatt dass WebAPI feststellte, dass es sich um einen POST handelt

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

Ich wusste, dass es etwas Dummes sein musste (das deinen ganzen Tag verbraucht)

Nexxas
quelle
6

Chrome versucht häufig, einen OPTIONSAnruf zu tätigen , bevor ein Beitrag verfasst wird. Dadurch wird sichergestellt, dass die CORS-Header in Ordnung sind. Es kann problematisch sein, wenn Sie den OPTIONSAufruf in Ihrem API-Controller nicht bearbeiten .

public void Options() { }
Nate Zaugg
quelle
6

Dieser Fehler kann auch auftreten, wenn Sie versuchen, eine Verbindung zu http herzustellen, während sich der Server auf https befindet.

Es war ein bisschen verwirrend, weil meine Get-Anfragen in Ordnung waren, das Problem war nur bei Post-Anfragen vorhanden.

FrankyHollywood
quelle
4

Ich habe den 405 bei meinem GET-Aufruf erhalten, und es stellte sich heraus, dass ich den Parameter in der serverseitigen GET-Methode benannt habe Get(int formId)und die Route ändern oder umbenennen musste Get(int id).

Sako73
quelle
4

Sie können den Fehler 405 auch erhalten, wenn Ihre Methode einen Parameter erwartet und Sie ihn nicht übergeben.

Dies funktioniert NICHT (405 Fehler)

HTML-Ansicht / Javascript

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

Web-API:

public HttpResponseMessage GetNews(int id)

Wenn die Methodensignatur wie oben beschrieben ist, müssen Sie Folgendes tun:

HTML-Ansicht / Javascript

$.ajax({
         url: '/api/News/5',
         //.....
Tom Stickel
quelle
Ich scheine aus verschiedenen Gründen auf 405-Fehler zu stoßen. Sie alle laufen darauf hinaus, dass versucht wird, die Methodensignatur und ein Parameterproblem oder ein Problem mit der Namensgebung von Konventionen oder ein Attributproblem usw. zu treffen.
Tom Stickel
4

Wenn Sie eine Route wie haben

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

Sie müssen genau den gleichen Parameternamen in der Methode verwenden, z

public ReactorModel GetReactor(reactorId)
{
 ...
}

Wenn Sie nicht genau denselben Parameter übergeben, wird möglicherweise der Fehler "405-Methode nicht zulässig" angezeigt, da die Route nicht mit der Anforderung übereinstimmt und WebApi eine andere Controller-Methode mit einer anderen zulässigen HTTP-Methode trifft.

Roylac
quelle
Dies ist auch keine Antwort!
Divyang Desai
@Div "405-Methode nicht zulässig" kann in dem von mir freigegebenen Fall angezeigt werden, da die Methode keinen API-Aufruf abfängt, da das Routen-Setup ungültig ist. Der API-Aufruf trifft dann möglicherweise eine andere unbeabsichtigte Methode, für die möglicherweise eine andere HTTP-Aktion zulässig ist. Ja, ich stimme zu, dass diese Antwort möglicherweise nicht zu 100% für die eigentliche Frage relevant ist. Der Titel der Frage von Xardas ist jedoch nicht sehr spezifisch, und ich glaube, dass viele Leute hier landen, um nach Antworten auf die im Titel angegebene Frage zu suchen finde diese Antwort nützlich.
Roylac
4

Hier ist eine Lösung

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

Lösungsartikel zu docs.microsoft.com

und entfernen Sie WebDAV aus den Modulen

<remove name="WebDAVModule" />

Danushka Amith Weerasingha
quelle
3

Ich bin zu spät zu dieser Party, aber da nichts oben in den meisten Fällen entweder lebensfähig war oder funktionierte, wurde dies für mich endgültig gelöst.

Auf dem Server, auf dem die Site / der Dienst gehostet wurde, war eine Funktion erforderlich! HTTP-AKTIVIERUNG !!!

Server-Manager> Verwalten> Rollen und Funktionen hinzufügen> Weiter Weiter Weiter, bis Sie zu Funktionen> Unter .NET (jede Version) die Option HTTP-Aktivierung aktivieren. Beachten Sie auch, dass unter> net> WCF Services eine versteckt ist.

Das hat dann sofort geklappt! Das schmolz mein Gehirn

Monolithcode
quelle
2

Dies beantwortet Ihre spezifische Frage nicht, aber als ich das gleiche Problem hatte, bin ich hier gelandet und habe mir gedacht, dass mehr Leute das Gleiche tun könnten.

Das Problem war, dass ich meine Get-Methode unabsichtlich als statisch deklariert hatte . Ich habe dies einen ganzen Vormittag verpasst und es gab keine Warnungen von Attributen oder ähnlichem.

Falsch:

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

Richtig:

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

[HttpPost] ist unnötig!

[Route("")]
public void Post(ProductModel data)
{
    ...
}
user3963793
quelle
Ja, die Art und Weise, wie Sie es tun, ist insofern richtig, als Sie kein explizites [HttpPost] benötigen. Es gibt jedoch einige Leute, die nicht der Konvention folgen (yikes) und daher so etwas wie [Route ("MyMethodSaver"] public string MyMethodtoSave (int? id) -> das würde einen [HttpPost] brauchen und es würde dann funktionieren
Tom Stickel
2

Ich konnte das NICHT lösen. Ich hatte CORS aktiviert und arbeitete, solange der POST ungültig war (ASP.NET 4.0 - WEBAPI 1). Als ich versuchte, eine HttpResponseMessage zurückzugeben, erhielt ich die HTTP 405-Antwort.

Aufgrund der obigen Antwort von Llad habe ich mir meine eigenen Referenzen angesehen.

Ich hatte das Attribut [System.Web.Mvc.HttpPost] über meiner POST-Methode aufgelistet.

Ich habe dies geändert, um Folgendes zu verwenden:

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

Das hat mein Leid behoben. Ich hoffe das hilft jemand anderem.

Der Vollständigkeit halber hatte ich Folgendes in meiner 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>
Spencer Sullivan
quelle
Dies hat die Methode, die für die OPTIONS-Vorfluganforderung (sowie für POST) aufgerufen wird. Zu diesem Zeitpunkt jsonist dies wahrscheinlich, nullda Vorfluganforderungen normalerweise keine Nutzdaten haben, oder Sie führen die Nachaktion zweimal aus.
Glennsl
1

Wir hatten ein ähnliches Problem. Wir haben versucht, von:

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

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

    }

}

Also würden wir .GET("/api/car")und das würde ein werfen 405 error.


Die Reparatur:

Die CarController.csDatei befand sich im Verzeichnis/api/car Als wir diesen API-Endpunkt anforderten, sendete IIS einen Fehler zurück, da es so aussah, als würden wir versuchen, auf ein virtuelles Verzeichnis zuzugreifen, auf das wir nicht zugreifen durften.

Option 1: Ändern / Umbenennen des Verzeichnisses, in dem sich der Controller befindet.
Option 2: Ändern Sie das Routenpräfix in ein Verzeichnis, das nicht mit dem virtuellen Verzeichnis übereinstimmt.

Zze
quelle
1

In meinem Fall hatte ich einen physischen Ordner im Projekt mit demselben Namen wie die WebAPI-Route (z. B. Sandbox) und nur die POST-Anforderung wurde vom statischen Dateihandler in IIS (offensichtlich) abgefangen.

Ein irreführender 405-Fehler anstelle des eher erwarteten 404-Fehlers war der Grund, warum ich lange für die Fehlerbehebung gebraucht habe.

Nicht leicht darauf hereinzufallen, aber möglich. Hoffe es hilft jemandem.

Panos Roditakis
quelle
0

Checken Sie die .csproj-Datei Ihres Projekts ein und ändern Sie sie

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

zu Ihrer Website URL wie folgt

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

Ein weiteres mögliches Problem, das dasselbe Verhalten verursacht, sind die Standardparameter im Routing. In meinem Fall wurde der Controller korrekt gefunden und instanziiert, aber der POST wurde aufgrund der angegebenen Standardaktion blockiert Get:

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

Ich hatte genau das gleiche Problem. Ich suchte zwei Stunden lang ohne Glück, was falsch war, bis mir klar wurde, dass meine POSTMethode privatestattdessen warpublic .

Lustig jetzt zu sehen, dass die Fehlermeldung irgendwie generisch ist. Ich hoffe es hilft!

Gonzo345
quelle
0

Stellen Sie sicher, dass Ihr Controller von der ControllerKlasse erbt .

Es könnte sogar verrückter sein, dass Sachen auch ohne das lokal funktionieren würden.

RAM
quelle
0

Mein POST-Handler hatte meinerseits folgende Form:

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

Ich fand heraus, dass ich die Argumente austauschen musste, dh zuerst die Körperdaten und dann den Routenparameter, wie folgt:

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