ASP.NET Web Api: ทรัพยากรที่ร้องขอไม่รองรับเมธอด http 'GET'


93

ฉันมีการดำเนินการต่อไปนี้ใน ApiController:

public string Something()
{
    return "value";
}

และฉันได้กำหนดเส้นทางของฉันดังนี้:

routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

ในรุ่นเบต้าสิ่งนี้ใช้ได้ดี แต่ฉันเพิ่งอัปเดตเป็นผู้สมัครรุ่นล่าสุดและตอนนี้ฉันพบข้อผิดพลาดในการโทรเช่นนี้:

ทรัพยากรที่ร้องขอไม่รองรับเมธอด http "GET"

ทำไมไม่ทำงานอีกต่อไป?

(ฉันคิดว่าฉันสามารถกำจัด {action} และสร้างตัวควบคุมจำนวนมากได้ แต่มันรู้สึกยุ่งเหยิง)

คำตอบ:


108

หากคุณไม่ได้กำหนดค่า HttpMethod ใด ๆ ในการกระทำของคุณในคอนโทรลเลอร์จะถือว่าเป็นเพียง HttpPost ใน RC ในเบต้าจะถือว่ารองรับวิธีการทั้งหมด - GET, PUT, POST และ Delete นี่เป็นการเปลี่ยนแปลงเล็กน้อยจากเบต้าเป็น RC คุณสามารถถอดรหัสวิธีการ http มากกว่าหนึ่งรายการได้อย่างง่ายดายด้วย [AcceptVerbs ("GET", "POST")]


เพิ่งพบสิ่งนี้ขอบคุณสำหรับการแก้ไข แต่อยากรู้ว่าทำไมฉันต้องทำสิ่งนี้ด้วยวิธีการที่กำหนดเองของฉัน แต่ไม่ใช่วิธีการ "รับ" เริ่มต้น ฉันมีเมธอด Get ที่สร้างโดยเทมเพลตสำหรับคอนโทรลเลอร์ แต่ไม่ได้รับการตกแต่ง นี่เป็นเพียงการประชุมเพราะชื่อ Get?
SelAromDotNet

3
@ จอช: ครับ! เมื่อชื่อของวิธีการดำเนินการขึ้นต้นด้วย "Get ... " คุณไม่จำเป็นต้องทำเครื่องหมายว่าเป็นเมธอด GET อ่านเพิ่มเติมได้ที่นี่: asp.net/web-api/overview/web-api-routing-and-actions/…
Jenny O'Reilly

ฉันทำตามที่แนะนำในคำตอบ แต่ตอนนี้ทั้งการโทรรับและโพสต์ของฉันกำลังถูกเปลี่ยนเส้นทางไปที่ Get Action กรุณาช่วย?
Syed Ali Taqi

55

ข้อมูลข้างต้นทั้งหมดถูกต้องฉันต้องการชี้ให้เห็นว่า[AcceptVerbs()]คำอธิบายประกอบมีอยู่ทั้งในเนมสเปซ System.Web.Mvc และ System.Web.Http

คุณต้องการใช้ System.Web.Http หากเป็นตัวควบคุม Web API


@ เอริก. เยี่ยมมากนี่คือเหตุผลที่มันไม่ได้ผลสำหรับฉัน ฉันมีคำกริยาในการกระทำของฉัน แต่มันถูกอ้างอิงผ่าน Web.Mvc จึงไม่ทำงาน
dreza

เยี่ยมมากคุณช่วยวันของฉัน
Hossein Narimani Rad

ขอบคุณมากเพราะ System.Web.Mvc ไม่ดีสำหรับฉัน
Burak Karakuş

34

แม้ว่านี่จะไม่ใช่คำตอบสำหรับ OP แต่ฉันก็มีข้อผิดพลาดเดียวกันจากสาเหตุที่แตกต่างกันอย่างสิ้นเชิง ดังนั้นในกรณีนี้จะช่วยคนอื่น ...

ปัญหาสำหรับฉันคือพารามิเตอร์เมธอดที่ตั้งชื่อไม่ถูกต้องซึ่งทำให้ WebAPI กำหนดเส้นทางการร้องขอโดยไม่คาดคิด ฉันมีวิธีการต่อไปนี้ใน ProgrammesController ของฉัน:

[HttpGet]
public Programme GetProgrammeById(int id)
{
    ...
}

[HttpDelete]
public bool DeleteProgramme(int programmeId)
{
    ...
}

คำขอ DELETE ไปยัง ... / api / programs / 3 ไม่ได้รับการกำหนดเส้นทางไปยัง DeleteProgramme ตามที่ฉันคาดไว้ แต่ไปที่ GetProgrammeById เนื่องจาก DeleteProgramme ไม่มีชื่อพารามิเตอร์ของ id GetProgrammeById แน่นอนว่าปฏิเสธ DELETE เนื่องจากถูกทำเครื่องหมายว่ายอมรับ GET เท่านั้น

ดังนั้นการแก้ไขจึงง่ายมาก:

[HttpDelete]
public bool DeleteProgramme(int id)
{
    ...
}

และทั้งหมดเป็นอย่างดี ความผิดพลาดโง่ ๆ แต่ยากที่จะแก้ไข


1
หากใครใช้การกำหนดเส้นทาง url ลองทำเช่น [Route ("{programmeId = programmeId: int}")]
sree

1
นี่คือสำหรับฉัน WebApiConfig -> MapHttpRoutes มี -> routeTemplate: "api / {controller} / {id}" ดังนั้นจึงต้องใช้พารามิเตอร์ของ "id"
HockeyJ

1
คำตอบของคุณชี้ให้ฉันเห็นปัญหาของฉันซึ่งแตกต่างกันเล็กน้อยฉันเปลี่ยนชื่อพารามิเตอร์ [FromUri] หนึ่งรายการสำหรับวิธีการนี้และไม่ได้อัปเดตทางฝั่งไคลเอ็นต์
Matus

22

หากคุณกำลังตกแต่งวิธีการของคุณHttpGetให้เพิ่มสิ่งต่อไปนี้usingที่ด้านบนของตัวควบคุม:

using System.Web.Http;

หากคุณใช้อยู่System.Web.Mvcปัญหานี้อาจเกิดขึ้นได้


5
นี่เป็นเรื่องจริงและน่าขัน. NET ไม่ได้แสดงข้อความอย่างชัดเจน
Teoman shipahi

15

นี่เป็นการเปลี่ยนแปลงจากเบต้าเป็น RC อย่างแน่นอน ในตัวอย่างที่ให้ไว้ในคำถามตอนนี้คุณต้องตกแต่งการกระทำของคุณด้วย [HttpGet] หรือ [AcceptVerbs ("GET")]

สิ่งนี้ทำให้เกิดปัญหาหากคุณต้องการผสมการกระทำที่ใช้คำกริยา (เช่น "GetSomething", "PostSomething") กับการกระทำที่ไม่ใช่คำกริยา หากคุณพยายามใช้แอตทริบิวต์ข้างต้นจะทำให้เกิดความขัดแย้งกับการกระทำที่ใช้คำกริยาในคอนโทรลเลอร์ วิธีหนึ่งในการกระตุ้นซึ่งจะกำหนดเส้นทางแยกกันสำหรับคำกริยาแต่ละคำและตั้งค่าการกระทำเริ่มต้นเป็นชื่อของคำกริยา วิธีนี้สามารถใช้เพื่อกำหนดทรัพยากรลูกใน API ของคุณ ตัวอย่างเช่นรหัสต่อไปนี้รองรับ: "/ resource / id / children" โดยที่ id และ children เป็นทางเลือก

        context.Routes.MapHttpRoute(
           name: "Api_Get",
           routeTemplate: "{controller}/{id}/{action}",
           defaults: new { id = RouteParameter.Optional, action = "Get" },
           constraints: new { httpMethod = new HttpMethodConstraint("GET") }
        );

        context.Routes.MapHttpRoute(
           name: "Api_Post",
           routeTemplate: "{controller}/{id}/{action}",
           defaults: new { id = RouteParameter.Optional, action = "Post" },
           constraints: new { httpMethod = new HttpMethodConstraint("POST") }
        );

หวังว่า Web API เวอร์ชันอนาคตจะรองรับสถานการณ์นี้ได้ดีขึ้น ขณะนี้เป็นเรื่องที่ลงทะเบียนในโครงการ CodePlex aspnetwebstack ที่ http://aspnetwebstack.codeplex.com/workitem/184 หากนี่คือสิ่งที่คุณต้องการเห็นโปรดลงคะแนนให้กับปัญหานี้


8

มีการตั้งค่าเดียวกันกับ OP ตัวควบคุมหนึ่งตัวที่มีการกระทำหลายอย่าง ... "ยุ่ง" น้อย :-)

ในกรณีของฉันฉันลืม "[HttpGet]" เมื่อเพิ่มการดำเนินการใหม่

[HttpGet]
public IEnumerable<string> TestApiCall()
{
    return new string[] { "aa", "bb" };
}

6

ปัญหาเดียวกันกับด้านบน แต่รูทต่างกันอย่างมาก สำหรับฉันมันคือการที่ฉันกดจุดสิ้นสุดด้วยกฎการเขียนซ้ำ https การกดปุ่มบน http ทำให้เกิดข้อผิดพลาดทำงานตามที่คาดไว้กับ https


3

แทนที่รหัสต่อไปนี้ในเส้นทางนี้

เส้นทาง:

App_Start => WebApiConfig.cs

รหัส:

config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}/{Param}",
            defaults: new { id = RouteParameter.Optional,
                            Param = RouteParameter.Optional }
                          );

1

ฉันไม่รู้ว่าสิ่งนี้เกี่ยวข้องกับโพสต์ของ OP หรือไม่ แต่ฉันไม่มีคำอธิบายประกอบ [HttpGet] และนั่นคือสิ่งที่ทำให้เกิดข้อผิดพลาดตามที่ระบุโดยวิธีการ @dinesh_ravva จะถือว่าเป็น HttpPost ตามค่าเริ่มต้น


0

ปัญหาของฉันง่ายพอ ๆ กับการมีข้อมูลอ้างอิงที่เป็นโมฆะซึ่งไม่ปรากฏในข้อความที่ส่งคืนฉันต้องดีบัก API เพื่อดู


0

ฉันได้รับข้อผิดพลาดนี้เมื่อเรียกใช้แบบสอบถามโดยไม่มี SSL

เพียงแค่เปลี่ยนรูปแบบ URL ของคำขอของฉันจาก HTTP เป็น HTTPS ก็แก้ไขได้


@cizario ฉันไม่เห็นด้วย - ดูเหมือนว่าจะพยายามตอบคำถาม ฉันกำลังโหวตว่า "ดูดี" สำหรับอันนี้
EJoshuaS - คืนสถานะ Monica เมื่อ

@ EJoshuaS-ReinstateMonica ดูเหมือนว่าความคิดเห็นไม่ใช่คำตอบที่แท้จริงสำหรับคำถาม จากคำตอบที่ยอมรับและคำตอบอื่น ๆ ด้านล่างปัญหาดูเหมือนจะไม่เกี่ยวข้องกับสคีมา
cizario

@cizario คำตอบที่ผิดไม่มีคุณภาพต่ำมาก - ถ้าคุณคิดว่าคำตอบนั้นผิดคุณควรลงคะแนน โปรดดู: คำตอบที่ผิดอย่างโจ่งแจ้งมีคุณภาพต่ำมากหรือไม่?
EJoshuaS - คืนสถานะ Monica เมื่อ

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