Metode 405 tidak diizinkan API Web

90

Kesalahan ini sangat umum, dan saya mencoba semua solusi dan tidak ada yang berhasil. Saya telah menonaktifkan penerbitan WebDAV di panel kontrol dan menambahkan ini ke file konfigurasi web saya:

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

Kesalahan masih berlanjut. Ini pengontrolnya:

   static readonly IProductRepository repository = new ProductRepository();

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

Implementasi metode:

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

Dan di sinilah pengecualian dilemparkan:

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

Ada saran?

Xardas
sumber

Jawaban:

62

Anda sedang melakukan POSTING dari klien:

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

tidak PUTing.

Metode API Web Anda hanya menerima permintaan PUT.

Begitu:

await client.PutAsJsonAsync("api/products", product);
Darin Dimitrov
sumber
Kesalahan 'HttpClient' tidak mengandung definisi untuk 'PostAsJsonAsync' dilempar, ketika mencoba kode Anda.
agileDev
61

Saya memiliki pengecualian yang sama. Masalah saya adalah saya telah menggunakan:

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

SEHARUSNYA

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

Saya mencoba banyak hal untuk mendapatkan kerja metode DELETE (saya mendapatkan metode 405 tidak diizinkan api web), dan akhirnya saya menambahkan [Route ("api / scan / {id}")] ke pengontrol saya dan berfungsi dengan baik. semoga posting ini membantu seseorang.

     // 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);
    }
pengguna2662006
sumber
Untuk beberapa alasan saya itu hanya tidak berfungsi untuk menghapus, untuk membuat dan memperbaruinya berfungsi dengan baik. Nah, saya baru saja menambahkan [HttpPost] dan berhasil. Tapi terima kasih, Anda membuat saya di jalur yang benar dan sekarang hanya menghabiskan biaya 5 menit :)
Rubenisme
1
Mengapa Anda tidak menambahkan atribut [HttpDelete] saja?
johnny 5
14

Masalah saya ternyata adalah Perutean Atribut di WebAPI. Saya membuat rute khusus, dan itu memperlakukannya seperti GET daripada WebAPI menemukan itu adalah POST

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

Saya tahu itu pasti sesuatu yang konyol (yang menghabiskan seluruh hari Anda)

Nexxas
sumber
Ini menyelamatkan hariku!
Phate01
6

Chrome sering kali mencoba melakukan OPTIONSpanggilan sebelum melakukan posting. Ini dilakukan untuk memastikan tajuk CORS teratur. Ini bisa menjadi masalah jika Anda tidak menangani OPTIONSpanggilan di pengontrol API Anda.

public void Options() { }
Nate Zaugg
sumber
6

Galat ini juga dapat terjadi saat Anda mencoba menyambung ke http saat server menggunakan https.

Agak membingungkan karena get-request saya OK, masalahnya hanya ada pada post-request.

FrankyHollywood
sumber
4

Saya mendapatkan 405 pada panggilan GET saya, dan masalahnya ternyata saya menamai parameter dalam metode sisi server GET Get(int formId), dan saya perlu mengubah rute, atau mengganti namanya Get(int id).

Sako73
sumber
4

Anda juga bisa mendapatkan kesalahan 405 jika mengatakan metode Anda mengharapkan parameter dan Anda tidak meneruskannya.

Ini TIDAK berhasil (kesalahan 405)

Tampilan HTML / Javascript

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

Api Web:

public HttpResponseMessage GetNews(int id)

Dengan demikian jika metode signature seperti di atas maka yang harus Anda lakukan:

Tampilan HTML / Javascript

$.ajax({
         url: '/api/News/5',
         //.....
Tom Stickel
sumber
Saya tampaknya mengalami kesalahan 405 karena berbagai alasan, semuanya bermuara pada fakta itu mencoba untuk HIT tanda tangan metode dan masalah parameter atau masalah penamaan konvensi atau masalah Atribut dll ...
Tom Stickel
4

Saya terlambat ke pesta ini tetapi karena tidak ada hal di atas yang layak atau berfungsi dalam banyak kasus, berikut adalah bagaimana hal ini akhirnya diselesaikan untuk saya.

Di server tempat situs / layanan dihosting, diperlukan fitur! AKTIVASI HTTP !!!

Manajer Server> Kelola> Tambahkan Peran dan Fitur> selanjutnya berikutnya hingga Anda masuk ke Fitur> Di bawah .NET (setiap versi) centang Aktivasi HTTP. Perhatikan juga ada satu yang tersembunyi di bawah> net> WCF Services.

Ini kemudian bekerja secara instan! Itu melelehkan otak saya

Kode monolit
sumber
4

Jika Anda memiliki rute seperti

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

Anda perlu menggunakan nama parameter yang sama persis dalam metode misalnya

public ReactorModel GetReactor(reactorId)
{
 ...
}

Jika Anda tidak meneruskan parameter yang sama persis, Anda mungkin mendapatkan kesalahan "metode 405 tidak diizinkan" karena rute tidak akan cocok dengan permintaan dan WebApi akan menekan metode pengontrol berbeda dengan metode HTTP yang diizinkan berbeda.

roylac
sumber
Ini juga bukan jawaban!
Divyang Desai
@Div "metode 405 tidak diizinkan" dapat ditampilkan dalam kasus yang saya bagikan karena metode tersebut tidak akan menangkap api-call karena pengaturan rute tidak valid. Api-call kemudian dapat mengenai metode lain yang tidak diinginkan yang dapat mengizinkan tindakan HTTP berbeda. Ya, saya setuju bahwa jawaban ini mungkin tidak 100% relevan dengan pertanyaan sebenarnya, namun judul pertanyaan oleh Xardas tidak terlalu spesifik dan saya yakin banyak orang yang datang ke sini untuk mencari jawaban atas pertanyaan seperti yang dinyatakan oleh judul temukan jawaban ini berguna.
roylac
4

Inilah salah satu solusinya

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

artikel solusi docs.microsoft.com

dan hapus WebDAV dari modul

<remove name="WebDAVModule" />

Danushka Amith Weerasingha
sumber
3

Ini tidak menjawab pertanyaan spesifik Anda, tetapi ketika saya memiliki masalah yang sama, saya berakhir di sini dan saya pikir lebih banyak orang mungkin melakukan hal yang sama.

Masalah yang saya hadapi adalah bahwa saya tanpa sengaja menyatakan metode Dapatkan saya sebagai statis . Saya melewatkan ini sepanjang pagi hari, dan itu tidak menyebabkan peringatan dari atribut atau yang serupa.

Salah:

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

Benar:

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

[HttpPost] tidak perlu!

[Route("")]
public void Post(ProductModel data)
{
    ...
}
pengguna3963793
sumber
1
Ya, cara Anda melakukannya benar karena Anda tidak memerlukan [HttpPost] eksplisit, namun ada beberapa orang yang tidak mengikuti konvensi (yikes) dan dengan demikian sesuatu seperti [Route ("MyMethodSaver"] public string MyMethodtoSave (int? id) -> yang akan membutuhkan [HttpPost] dan kemudian akan berfungsi
Tom Stickel
2

Saya TIDAK bisa menyelesaikan ini. Saya telah mengaktifkan CORS dan bekerja selama POST kembali kosong (ASP.NET 4.0 - WEBAPI 1). Ketika saya mencoba mengembalikan HttpResponseMessage, saya mulai mendapatkan respons HTTP 405.

Berdasarkan tanggapan Llad di atas, saya melihat referensi saya sendiri.

Saya memiliki atribut [System.Web.Mvc.HttpPost] yang tercantum di atas metode POST saya.

Saya mengubah ini untuk menggunakan:

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

Ini memperbaiki kesedihan saya. Saya harap ini membantu orang lain.

Demi kelengkapan, saya memiliki yang berikut di web.config saya:

<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
sumber
Ini akan memiliki metode yang dipanggil pada OPTIONS permintaan pra-penerbangan (serta pada POST), pada titik mana jsonkemungkinan nullkarena permintaan pra-penerbangan biasanya tidak memiliki muatan, atau Anda akan menjalankan tindakan pasca dua kali.
glennsl
1

Kami mengalami masalah serupa. Kami mencoba MENDAPATKAN dari:

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

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

    }

}

Jadi kami akan .GET("/api/car")dan ini akan melempar 405 error.


Perbaiki:

The CarController.csberkas berada di direktori/api/car jadi ketika kami meminta api endpoint ini, IIS akan mengirim kembali kesalahan karena itu tampak seperti kami berusaha untuk mengakses direktori virtual yang kami tidak diperbolehkan untuk.

Opsi 1: Ubah / ganti nama direktori pengontrol berada di
Opsi 2: ubah awalan rute ke sesuatu yang tidak cocok dengan direktori virtual.

Zze
sumber
1

Dalam kasus saya, saya memiliki folder fisik dalam proyek dengan nama yang sama dengan rute WebAPI (misalnya sandbox) dan hanya permintaan POST yang dicegat oleh penangan file statis di IIS (jelas).

Mendapatkan kesalahan 405 yang menyesatkan, bukan 404 yang lebih diharapkan, adalah alasan saya butuh waktu lama untuk memecahkan masalah.

Tidak mudah untuk jatuh ke dalam ini, tapi mungkin. Semoga bisa membantu seseorang.

Panos Roditakis
sumber
1

Bagi saya, penangan POST saya adalah dari bentuk ini:

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

Saya menemukan bahwa saya harus menukar argumen , yaitu data tubuh terlebih dahulu kemudian parameter rute, seperti ini:

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

periksa file .csproj proyek Anda dan ubah

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

ke url situs web Anda seperti ini

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

Masalah lain yang mungkin menyebabkan perilaku yang sama adalah parameter default dalam perutean. Dalam kasus saya, pengontrol ditempatkan dan dibuat dengan benar, tetapi POST diblokir karena Gettindakan default ditentukan:

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

Saya mengalami masalah yang persis sama. Saya mencari selama dua jam apa yang salah tanpa hasil sampai saya menyadari POSTmetode saya adalah privategantinya public.

Lucu sekarang melihat pesan kesalahan itu agak umum. Semoga membantu!

Gonzo345
sumber
0

Pastikan pengontrol Anda mewarisi dari Controllerkelas.

Bahkan mungkin lebih gila lagi bahwa barang-barang akan bekerja secara lokal bahkan tanpa itu.

Ram
sumber