วิธีการ 405 ไม่อนุญาตให้ใช้ Web API


90

ข้อผิดพลาดนี้เกิดขึ้นบ่อยมากและฉันได้ลองวิธีแก้ปัญหาทั้งหมดแล้ว แต่ก็ไม่ได้ผล ฉันได้ปิดใช้งานการเผยแพร่ WebDAV ในแผงควบคุมและเพิ่มสิ่งนี้ลงในไฟล์กำหนดค่าเว็บของฉัน:

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

ข้อผิดพลาดยังคงมีอยู่ นี่คือตัวควบคุม:

   static readonly IProductRepository repository = new ProductRepository();

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

วิธีการใช้งาน:

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

และนี่คือจุดที่เกิดข้อยกเว้น:

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

ข้อเสนอแนะใด ๆ ?

คำตอบ:


62

คุณกำลังโพสต์จากไคลเอนต์:

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

ไม่วาง

วิธี Web API ของคุณยอมรับเฉพาะคำขอ PUT

ดังนั้น:

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

ข้อผิดพลาด 'HttpClient' ไม่มีคำจำกัดความสำหรับ 'PostAsJsonAsync' เมื่อลองใช้รหัสของคุณ
agileDev

61

ฉันมีข้อยกเว้นเหมือนกัน ปัญหาของฉันคือฉันใช้:

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

ควรจะเป็น

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

18

ฉันลองหลายอย่างเพื่อให้เมธอด DELETE ทำงานได้ (ฉันได้รับ 405 method ไม่อนุญาตให้ใช้ web api) และในที่สุดฉันก็เพิ่ม[Route ("api / scan / {id}")] ลงในคอนโทรลเลอร์ของฉันและก็ใช้ได้ดี หวังว่าโพสต์นี้จะช่วยได้บ้าง

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

ด้วยเหตุผลบางอย่างฉันใช้งานไม่ได้สำหรับการลบเท่านั้นสำหรับการสร้างและอัปเดตมันทำงานได้ดี ฉันเพิ่งเพิ่ม [HttpPost] และมันใช้งานได้ แต่ขอบคุณคุณทำให้ฉันมาถูกทางแล้วและเสียค่าใช้จ่ายเพียง 5 นาทีเท่านั้น :)
Rubenisme

1
ทำไมคุณไม่เพิ่มแอตทริบิวต์ [HttpDelete] ล่ะ
5

14

ปัญหาของฉันกลายเป็น Attribute Routing ใน WebAPI ฉันสร้างเส้นทางที่กำหนดเองและปฏิบัติเหมือน GET แทนที่จะเป็น WebAPI โดยพบว่าเป็น POST

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

ฉันรู้ว่ามันต้องเป็นอะไรที่งี่เง่า (ที่กินไปทั้งวัน)


วันนี้ช่วยฉันไว้!
Phate01

6

บ่อยครั้งที่ Chrome พยายามOPTIONSโทรออกก่อนที่จะโพสต์ ทำเช่นนี้เพื่อให้แน่ใจว่าส่วนหัว CORS อยู่ในลำดับ อาจเป็นปัญหาได้หากคุณไม่ได้จัดการการOPTIONSโทรในตัวควบคุม API ของคุณ

public void Options() { }

6

ข้อผิดพลาดนี้อาจเกิดขึ้นได้เมื่อคุณพยายามเชื่อมต่อกับ http ในขณะที่เซิร์ฟเวอร์อยู่บน https

มันค่อนข้างสับสนเพราะคำขอรับของฉันโอเคปัญหาเกิดขึ้นกับคำขอโพสต์เท่านั้น


4

ผมได้รับ 405 ที่โทร GET ของฉันและปัญหาที่เกิดขึ้นกลับกลายเป็นว่าผมตั้งชื่อพารามิเตอร์ใน GET วิธีการด้านเซิร์ฟเวอร์ที่และฉันต้องการที่จะเปลี่ยนเส้นทางหรือเปลี่ยนชื่อGet(int formId)Get(int id)


4

คุณยังสามารถรับข้อผิดพลาด 405 ได้หากบอกว่าเมธอดของคุณคาดหวังพารามิเตอร์และคุณไม่ได้ส่งผ่าน

สิ่งนี้ใช้ไม่ได้ (ข้อผิดพลาด 405)

ดู HTML / Javascript

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

เว็บ API:

public HttpResponseMessage GetNews(int id)

ดังนั้นหากลายเซ็นของวิธีเป็นเหมือนข้างต้นคุณต้องทำ:

ดู HTML / Javascript

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

ดูเหมือนว่าฉันจะพบข้อผิดพลาด 405 ด้วยเหตุผลหลายประการพวกเขาทำทั้งหมดลงไปที่ความจริงที่ว่ามันพยายามที่จะ HIT ลายเซ็นวิธีและปัญหาพารามิเตอร์หรือปัญหาการตั้งชื่อแบบประชุมหรือปัญหาแอตทริบิวต์ ฯลฯ ...
Tom Stickel

4

ฉันมางานปาร์ตี้นี้ช้า แต่เนื่องจากไม่มีอะไรข้างต้นไม่ว่าจะเป็นไปได้หรือทำงานได้ในกรณีส่วนใหญ่นี่คือวิธีการแก้ไขในที่สุดสำหรับฉัน

บนเซิร์ฟเวอร์ที่ไซต์ / บริการโฮสต์อยู่จำเป็นต้องมีคุณลักษณะ! การเปิดใช้งาน HTTP !!!

ตัวจัดการเซิร์ฟเวอร์> จัดการ> เพิ่มบทบาทและคุณสมบัติ> ถัดไปถัดไปจนกว่าคุณจะไปที่คุณสมบัติ> ภายใต้. NET (แต่ละเวอร์ชัน) ทำเครื่องหมายการเปิดใช้งาน HTTP นอกจากนี้โปรดทราบว่ามีหนึ่งรายการที่ซ่อนอยู่ใต้> net> WCF Services

สิ่งนี้ใช้งานได้ทันที! นั่นกำลังละลายสมองของฉัน


4

หากคุณมีเส้นทางเช่น

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

คุณต้องใช้ชื่อพารามิเตอร์เดียวกันในวิธีการเช่น

public ReactorModel GetReactor(reactorId)
{
 ...
}

หากคุณไม่ผ่านพารามิเตอร์เดียวกันทั้งหมดคุณอาจได้รับข้อผิดพลาด "405 method not allowed" เนื่องจากเส้นทางจะไม่ตรงกับคำขอและ WebApi จะเข้าสู่วิธีการควบคุมอื่นด้วยวิธี HTTP ที่อนุญาตอื่น


นี่ไม่ใช่คำตอบเช่นกัน!
Divyang Desai

@Div "ไม่อนุญาตวิธี 405" สามารถแสดงได้ในกรณีที่ฉันแชร์เนื่องจากเมธอดจะไม่จับ api-call เนื่องจากการตั้งค่าเส้นทางไม่ถูกต้อง จากนั้น api-call อาจเข้าสู่วิธีการอื่นที่ไม่ได้ตั้งใจซึ่งอาจอนุญาตให้มีการดำเนินการ HTTP อื่น ใช่ฉันยอมรับว่าคำตอบนี้อาจไม่ตรงกับคำถามจริง 100% อย่างไรก็ตามชื่อคำถามของ Xardas ไม่เฉพาะเจาะจงมากนักและฉันเชื่อว่าหลายคนมาที่นี่เพื่อค้นหาคำตอบของคำถามตามที่ระบุไว้ในชื่อเรื่องอาจ พบว่าคำตอบนี้มีประโยชน์
roylac


3

สิ่งนี้ไม่ได้ตอบคำถามเฉพาะของคุณ แต่เมื่อฉันมีปัญหาเดียวกันฉันก็มาพบที่นี่และฉันคิดว่าอาจมีคนทำเช่นเดียวกันมากขึ้น

ปัญหาที่ฉันพบคือฉันได้ประกาศวิธี Get ของฉันเป็นแบบคงที่โดยไม่เจตนา ฉันพลาดสิ่งนี้ไปตลอดช่วงบ่ายและไม่มีคำเตือนจากคุณลักษณะหรือสิ่งที่คล้ายกัน

ไม่ถูกต้อง:

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

แก้ไข:

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

2

[HttpPost] ไม่จำเป็น!

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

1
ใช่วิธีที่คุณทำนั้นถูกต้องโดยที่คุณไม่จำเป็นต้องมี [HttpPost] ที่ชัดเจนอย่างไรก็ตามมีบางคนไม่ปฏิบัติตามแบบแผน (yikes) ดังนั้นบางอย่างเช่น [Route ("MyMethodSaver"] สตริงสาธารณะ MyMethodtoSave (int? id) -> ที่จะต้องมี [HttpPost] และจะใช้งานได้
Tom Stickel

2

ฉันไม่สามารถแก้ปัญหานี้ได้ ฉันเปิดใช้งาน CORS และทำงานได้ตราบเท่าที่ POST ส่งคืนเป็นโมฆะ (ASP.NET 4.0 - WEBAPI 1) เมื่อฉันพยายามส่งคืน HttpResponseMessage ฉันเริ่มได้รับการตอบสนอง HTTP 405

จากคำตอบของ Llad ข้างต้นฉันได้ดูข้อมูลอ้างอิงของตัวเอง

ฉันมีแอตทริบิวต์ [System.Web.Mvc.HttpPost] ที่ระบุไว้ข้างต้นวิธีการ POST ของฉัน

ฉันเปลี่ยนสิ่งนี้เพื่อใช้:

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

สิ่งนี้แก้ไขความทุกข์ของฉัน ฉันหวังว่านี่จะช่วยคนอื่นได้

เพื่อความสมบูรณ์ฉันมีสิ่งต่อไปนี้ใน 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>

วิธีนี้จะมีวิธีที่เรียกว่าคำขอก่อนการบินของ OPTIONS (เช่นเดียวกับ POST) ซึ่งjsonเป็นไปได้ว่าnullคำขอก่อนการบินมักจะไม่มีน้ำหนักบรรทุกหรือคุณจะเรียกใช้การดำเนินการโพสต์สองครั้ง
glennsl

1

เรามีปัญหาที่คล้ายกัน เราพยายามรับจาก:

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

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

    }

}

ดังนั้นเราจะและนี้จะโยน.GET("/api/car")405 error


การแก้ไข:

CarController.csไฟล์อยู่ในไดเรกทอรี/api/carดังนั้นเมื่อเราได้รับการร้องขอปลายทาง API นี้ IIS จะส่งกลับข้อผิดพลาดเนื่องจากมันดูเหมือนเรากำลังพยายามที่จะเข้าถึงไดเรกทอรีเสมือนว่าเราไม่ได้รับอนุญาตให้

ตัวเลือกที่ 1:เปลี่ยน / เปลี่ยนชื่อไดเร็กทอรีที่คอนโทรลเลอร์อยู่ใน
ตัวเลือกที่ 2:เปลี่ยนคำนำหน้าเส้นทางเป็นสิ่งที่ไม่ตรงกับไดเร็กทอรีเสมือน


1

ในกรณีของฉันฉันมีโฟลเดอร์ฟิสิคัลในโปรเจ็กต์ที่มีชื่อเดียวกับเส้นทาง WebAPI (เช่นแซนด์บ็อกซ์) และมีเพียงคำขอ POST เท่านั้นที่ถูกขัดขวางโดยตัวจัดการไฟล์แบบคงที่ใน IIS (เห็นได้ชัด)

การได้รับข้อผิดพลาด 405 ที่ทำให้เข้าใจผิดแทนที่จะเป็น 404 ที่คาดไว้มากกว่าเป็นสาเหตุที่ทำให้ฉันใช้เวลานานในการแก้ไขปัญหา

ไม่ใช่เรื่องง่ายที่จะตกหลุมพรางเรื่องนี้ แต่เป็นไปได้ หวังว่ามันจะช่วยใครบางคน


1

ในส่วนของฉันตัวจัดการ POST ของฉันอยู่ในรูปแบบนี้:

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

ฉันคิดว่าฉันต้องสลับอาร์กิวเมนต์นั่นคือการบอกว่าข้อมูลร่างกายก่อนจากนั้นจึงเป็นพารามิเตอร์เส้นทางดังนี้:

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

0

ตรวจสอบในไฟล์. csproj โครงการของคุณและเปลี่ยนแปลง

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

ไปยัง url เว็บไซต์ของคุณเช่นนี้

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

0

ปัญหาที่เป็นไปได้อีกประการที่ทำให้เกิดพฤติกรรมเดียวกันคือพารามิเตอร์เริ่มต้นในการกำหนดเส้นทาง ในกรณีของฉันตัวควบคุมตั้งอยู่และสร้างอินสแตนซ์อย่างถูกต้อง แต่ POST ถูกบล็อกเนื่องจากGetการกระทำเริ่มต้นที่ระบุ:

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

0

ฉันมีปัญหาเดียวกัน ฉันมองหาสิ่งผิดปกติเป็นเวลาสองชั่วโมงโดยไม่มีโชคจนกระทั่งฉันรู้ว่าPOSTวิธีการของฉันprivateแทนที่จะเป็นpublicแทน

ตอนนี้ตลกดีที่เห็นว่าข้อความแสดงข้อผิดพลาดเป็นเรื่องธรรมดา หวังว่าจะช่วยได้!


0

ตรวจสอบให้แน่ใจว่าคอนโทรลเลอร์ของคุณสืบทอดมาจาก Controllerคลาส

มันอาจจะบ้ากว่าที่สิ่งต่างๆจะทำงานได้ในท้องถิ่นแม้ว่าจะไม่มีก็ตาม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.