405 yöntemine izin verilmiyor Web API


90

Bu hata çok yaygındır ve tüm çözümleri denedim ve hiçbiri işe yaramadı. Kontrol panelinde WebDAV yayınlamayı devre dışı bıraktım ve bunu web yapılandırma dosyama ekledim:

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

Hata hala devam ediyor. Bu denetleyici:

   static readonly IProductRepository repository = new ProductRepository();

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

Yöntem uygulaması:

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

Ve burası istisnanın ortaya çıktığı yerdir:

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

Herhangi bir öneri?

Yanıtlar:


62

Müşteriden POST yapıyorsunuz:

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

PUT değil.

Web API yönteminiz yalnızca PUT isteklerini kabul eder.

Yani:

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

Kodunuzu denediğinizde 'HttpClient' hatası 'PostAsJsonAsync' için bir tanım içermiyor.
agileDev

61

Ben de aynı istisnaya sahiptim. Benim sorunum şuydu:

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

OLMALI

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

18

DELETE yönteminin çalışmasını sağlamak için birçok şey denedim (405 yöntemine izin verilmeyen web api alıyordum) ve son olarak denetleyicime [Route ("api / scan / {id}")] ekledim ve iyi çalışıyordu. umarım bu yazı birine yardımcı olur.

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

Bazı nedenlerden dolayı, sadece silme için çalışmıyordu, oluşturmak ve güncellemek için iyi çalıştı. Eh, [HttpPost] 'u ekledim ve işe yaradı. Ama teşekkürler, beni doğru yolda
tuttun ve

1
Neden sadece [HttpDelete] özniteliğini eklemiyorsunuz?
johnny 5

14

Sorunumun WebAPI'de Öznitelik Yönlendirme olduğu ortaya çıktı. Özel bir rota oluşturdum ve bir POST olduğunu keşfeden WebAPI yerine bir GET gibi davrandı

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

Bunun aptalca bir şey olması gerektiğini biliyordum (tüm gününüzü tüketen)


Bu benim günümü kurtardı!
Phate01

6

Chrome, çoğu zaman OPTIONSbir gönderi yapmadan önce arama yapmaya çalışır . Bunu, CORS başlıklarının sıralı olduğundan emin olmak için yapar. OPTIONSAPI denetleyicinizdeki çağrıyı işlemiyorsanız sorunlu olabilir .

public void Options() { }

6

Bu hata, sunucu https üzerindeyken http'ye bağlanmaya çalıştığınızda da ortaya çıkabilir.

Biraz kafa karıştırıcıydı çünkü alma isteklerim tamamdı, sorun yalnızca sonradan isteklerde mevcuttu.


4

GET çağrımda 405'i alıyordum ve sorun, parametreyi GET sunucu tarafı yönteminde Get(int formId)adlandırdığım ve rotayı değiştirmem veya yeniden adlandırmam gerektiği ortaya çıktı Get(int id).


4

Metodunuzun bir parametre beklediğini ve onu geçmediğinizi söylerseniz, 405 hatasını da alabilirsiniz.

Bu çalışmıyor (405 hatası)

HTML Görünümü / Javascript

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

Web Api:

public HttpResponseMessage GetNews(int id)

Dolayısıyla, yöntem imzası yukarıdaki gibiyse, yapmanız gerekenler:

HTML Görünümü / Javascript

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

Ben çeşitli nedenlerle 405 hataları içine çalışıyor olması gibi görünüyor, onlar yöntem imzası ve parametre sorun veya bir kongre adlandırma sorunu veya Özellik sorunu vb ... HIT teşebbüs aslında aşağı tüm çıban yapmak
Tom Stickel

4

Bu partiye geç kaldım, ancak yukarıdaki hiçbir şey ya uygulanabilir ya da çoğu durumda işe yaramadığı için, işte nihayet bu benim için nasıl çözüldü.

Site / hizmetin barındırıldığı sunucuda bir özellik gerekiyordu! HTTP ETKİNLEŞTİRME !!!

Sunucu Yöneticisi> Yönet> Rolleri ve Özellikleri Ekle> sonraki sonraki sırada Özellikler> .NET altında (her sürüm) HTTP Etkinleştirme'yi işaretleyin. Ayrıca> net> WCF Hizmetleri altında bir tane gizlendiğini unutmayın.

Bu daha sonra anında çalıştı! Bu beynimi eritiyordu


4

Gibi bir rotanız varsa

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

Yöntemde tam olarak aynı parametre adını kullanmanız gerekir, örn.

public ReactorModel GetReactor(reactorId)
{
 ...
}

Tam olarak aynı parametreyi geçmezseniz, yol istekle eşleşmeyeceği ve WebApi izin verilen farklı HTTP yöntemiyle farklı bir denetleyici yöntemine çarpacağı için "405 yöntemine izin verilmiyor" hatasını alabilirsiniz.


Bu da bir cevap değil!
Divyang Desai

@Div "405 metoduna izin verilmiyor", rota kurulumu geçersiz olduğu için metot api-call'ı yakalayamayacağı için paylaştığım durumda gösterilebilir. Api çağrısı daha sonra farklı bir HTTP eylemine izin verebilecek istenmeyen başka bir yönteme isabet edebilir. Evet, bu cevabın gerçek soruyla% 100 alakalı olmayabileceğini kabul ediyorum, ancak Xardas'ın sorusunun başlığı çok spesifik değil ve inanıyorum ki, başlıkta belirtildiği gibi soruya cevap aramak için buraya gelen birçok kişi olabilir bu cevabı faydalı bul.
roylac

3

Bu, sizin özel sorunuza cevap vermiyor, ama aynı problemi yaşadığımda buraya geldim ve daha fazla insanın aynı şeyi yapabileceğini düşündüm.

Karşılaştığım sorun, yanlışlıkla Get yöntemimi statik olarak ilan etmiş olmamdı . Bunu tüm bir öncesinden kaçırdım ve özelliklerden veya benzerlerinden hiçbir uyarıya neden olmadı.

Yanlış:

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

Doğru:

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


2

[HttpPost] gereksiz!

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

1
Evet, bunu yaptığınız yol doğrudur, çünkü açık bir [HttpPost] 'a ihtiyacınız yoktur, ancak bazı insanlar kuralı takip etmemektedir (yikes) ve dolayısıyla [Route ("MyMethodSaver"] public string MyMethodtoSave (int? id) -> bu bir [HttpPost] 'a ihtiyaç duyar ve daha sonra çalışır
Tom Stickel

2

Bunu çözemedim. POST geçersiz döndürdüğü sürece CORS'u etkinleştirdim ve çalıştım (ASP.NET 4.0 - WEBAPI 1). Bir HttpResponseMessage döndürmeye çalıştığımda, HTTP 405 yanıtını almaya başladım.

Llad'ın yukarıdaki cevabına dayanarak, kendi referanslarıma bir göz attım.

POST yöntemimin üzerinde listelenen [System.Web.Mvc.HttpPost] özniteliğine sahiptim.

Bunu kullanmak için değiştirdim:

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

Bu dertlerimi düzeltti. Umarım bunun bir başkasına yardımı olur.

Eksiksizlik adına web.config dosyamda aşağıdakiler vardı:

<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>

Bu, OPTIONS uçuş öncesi isteğinde (ve ayrıca POST'ta) çağrılan yönteme sahip olacaktır; bu noktada json, muhtemelen nulluçuş öncesi isteklerde genellikle yük bulunmadığından veya son eylemi iki kez çalıştıracaksınız.
glennsl

1

Benzer bir sorun yaşadık. Şunlardan GET almaya çalışıyorduk:

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

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

    }

}

Yani yapardık .GET("/api/car")ve bu bir 405 error.


Çözüm:

CarController.csDosya dizinde oldu/api/car bu API son nokta talep edildi ne zaman biz izin verilmemiştir ki bir sanal dizin erişmeye çalışıyorlardı benziyordu, çünkü IIS bir hata geri göndermek diye.

Seçenek 1: denetleyicinin bulunduğu dizini değiştirin / yeniden adlandırın
Seçenek 2: yol önekini sanal dizinle eşleşmeyen bir şeye değiştirin.


1

Benim durumumda, projede WebAPI yolu ile aynı ada sahip fiziksel bir klasörüm vardı (örn. Sanal alan) ve yalnızca POST isteği IIS'deki statik dosya işleyicisi tarafından durduruldu (tabii ki).

Daha çok beklenen 404 yerine yanıltıcı bir 405 hatası almak, sorun gidermemin uzun sürmesinin sebebiydi.

Buna düşmek kolay değil, ama mümkün. Umarım birine yardımcı olur.


1

Benim açımdan POST işleyicim şu biçimdeydi:

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

Argümanları , yani önce vücut verilerini, sonra rota parametresini değiştirmem gerektiğini anladım , şu şekilde:

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

0

proje .csproj dosyanızı kontrol edin ve değiştirin

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

web sitenizin url'sine bunun gibi

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

0

Aynı davranışa neden olan başka bir olası sorun, yönlendirmedeki varsayılan parametrelerdir. Benim durumumda denetleyici doğru bir şekilde konumlandırılmış ve somutlaştırılmıştır, ancak POST Getbelirtilen varsayılan eylem nedeniyle engellendi :

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

0

Ben de tamamen aynı sorunu yaşıyordum. Benim fark kadar hiçbir şans ile neyin yanlış olduğunu iki saat baktım POSTyöntemiydi privateyerine public.

Şimdi bu hata mesajını görmek biraz genel. Umarım yardımcı olur!


0

Denetleyicinizin Controllersınıftan miras aldığından emin olun .

Hatta bu olmadan bile yerel olarak işlerin yürümesi daha çılgınca olabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.