พารามิเตอร์ทางเลือกใน Web Api Attribute Routing


92

ฉันต้องการจัดการ POST ของ API-Call ต่อไปนี้:

/v1/location/deviceid/appid

พารามิเตอร์เพิ่มเติมมาจาก Post-Body

ทั้งหมดนี้ใช้ได้ดีสำหรับฉัน ตอนนี้ฉันต้องการขยายโค้ดของฉันโดยอนุญาตให้ "deviceid" และ / หรือ "appid" และ / หรือ BodyData เป็นโมฆะ:

/v1/location/deviceid
/v1/location/appid
/v1/location/

URL ทั้ง 3 นี้ควรตอบสนองด้วยเส้นทางเดียวกัน

แนวทางแรกของฉัน (จำเป็นต้องใช้ BodyData):

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody] location_fromuser BodyData)
{
    return repository.AddNewLocation(deviceid, appid, BodyData);
}

สิ่งนี้ใช้ไม่ได้และส่งกลับข้อผิดพลาดในการคอมไพล์:

"พารามิเตอร์ทางเลือกต้องอยู่ท้าย"

ลองครั้งต่อไป:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post([FromBody] location_fromuser BodyData, string deviceid = null, string appid = null)

ตอนนี้ฟังก์ชันของฉัน AddNewLocation () จะได้รับเสมอBodyData=null- แม้ว่าการโทรจะส่ง Body ก็ตาม

ในที่สุดฉันก็ตั้งค่าพารามิเตอร์ทั้ง 3 ตัวเลือก:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")]
public location_fromuser Post(string deviceid = null, string appid = null, [FromBody location_fromuser BodyData = null)

อย่าทำงาน:

พารามิเตอร์ตัวเลือกไม่ได้รับการสนับสนุนโดยBodyDataFormatterParameterBinding

เหตุใดฉันจึงต้องการโซลูชันที่มีพารามิเตอร์เสริม My Controller จัดการเฉพาะ "การเพิ่มตำแหน่งใหม่" ผ่าน POST

ฉันต้องการส่งข้อมูลที่ไม่ถูกต้องข้อยกเว้นหรือข้อความแสดงข้อผิดพลาดของฉันเอง แม้ว่าการโทรจะไม่มีค่าก็ตาม ในกรณีนี้ฉันต้องการให้สามารถตัดสินใจทิ้งข้อยกเว้นหรือการตั้งค่าเริ่มต้นด้วยรหัสของฉัน

คำตอบ:


181

สำหรับการร้องขอเข้ามาเหมือน/v1/location/1234ที่คุณสามารถคิดว่ามันจะเป็นเรื่องยากสำหรับ Web API โดยอัตโนมัติคิดออกถ้าค่าของส่วนที่สอดคล้องกับ '1234' จะเกี่ยวข้องกับการและไม่ให้appiddeviceid

ฉันคิดว่าคุณควรเปลี่ยนแม่แบบเส้นทางของคุณให้เป็นเหมือน [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]แล้วแยกวิเคราะห์deiveOrAppidเพื่อหาประเภทของรหัส

นอกจากนี้คุณต้องสร้างเซ็กเมนต์ในเทมเพลตเส้นทางด้วยตัวเองไม่เช่นนั้นจะถือว่ากลุ่มนั้นเป็นไปตามที่กำหนด สังเกต?อักขระในกรณีนี้ ตัวอย่างเช่น: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]


58
?ภายในเทมเพลตเส้นทางคือสิ่งที่ฉันกำลังมองหา +1
Kal_Torak

4
ฉันจะไม่บอกว่า "deviceOrAppId" เป็นตัวเลือกการออกแบบที่ดีที่สุด ฉันคิดว่า API ควรรู้อยู่เสมอว่าจะได้รับอะไรถ้าเป็นไปได้
Niels Brinch

14
เพื่อเป็นข้อมูล - เมื่อเราทำเครื่องหมายพารามิเตอร์เป็นทางเลือกในการดำเนินการ uri โดยใช้?อักขระเราจะต้องระบุค่าเริ่มต้นให้กับพารามิเตอร์ในลายเซ็นของวิธีการเช่น MyMethod (string name = "someDefaultValue", int? id = null)
RBT

@RBT คุณเป็น MVP ตัวจริงฉันนิ่งงันอยู่ที่นั่นสักครู่ ขอขอบคุณ!
sm

1
เย็น. ดีใจที่ได้ช่วยคุณ @sm ฉันได้แปลงความคิดเห็นเป็นคำตอบเพื่อการมองเห็นที่ดีขึ้นเพราะดูเหมือนว่าจะเป็นประโยชน์ มันจะเป็นส่วนเสริมของโพสต์ของ Kiran
RBT

47

ข้อมูลอื่น: หากคุณต้องการใช้Route Constraintลองนึกดูว่าคุณต้องการบังคับให้พารามิเตอร์นั้นมีประเภทข้อมูลintจากนั้นคุณต้องใช้ไวยากรณ์นี้:

[Route("v1/location/**{deviceOrAppid:int?}**", Name = "AddNewLocation")]

เดอะ? อักขระถูกใส่ไว้ก่อนอักขระสุดท้าย}เสมอ

สำหรับข้อมูลเพิ่มเติมโปรดดู: พารามิเตอร์ URI ที่เป็นทางเลือกและค่าเริ่มต้น


18

การแปลงความคิดเห็นของฉันเป็นคำตอบเพื่อเติมเต็มคำตอบของ @Kiran Chala เพราะดูเหมือนว่าจะเป็นประโยชน์สำหรับผู้ชม -

เมื่อเราทำเครื่องหมายพารามิเตอร์เป็นทางเลือกในการดำเนินการ uri โดยใช้?อักขระเราจะต้องระบุค่าเริ่มต้นให้กับพารามิเตอร์ในลายเซ็นวิธีการดังที่แสดงด้านล่าง:

MyMethod(string name = "someDefaultValue", int? Id = null)


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