เหตุใดจึงต้องมีFromBody
และFromUri
แอตทริบิวต์ใน ASP.NET Web API`
อะไรคือความแตกต่างระหว่างการใช้คุณลักษณะและไม่ได้ใช้งาน
เหตุใดจึงต้องมีFromBody
และFromUri
แอตทริบิวต์ใน ASP.NET Web API`
อะไรคือความแตกต่างระหว่างการใช้คุณลักษณะและไม่ได้ใช้งาน
คำตอบ:
เมื่อเว็บ ASP.NET API เรียกวิธีการในการควบคุมก็จะต้องตั้งค่าสำหรับพารามิเตอร์กระบวนการที่เรียกว่าพารามิเตอร์ที่มีผลผูกพัน
โดยค่าเริ่มต้น Web API ใช้กฎต่อไปนี้เพื่อผูกพารามิเตอร์:
ถ้าพารามิเตอร์เป็น"ง่าย" ประเภทเว็บ API พยายามที่จะได้รับค่าจาก URI ประเภทที่เรียบง่าย ได้แก่ . NET primitive types (int, bool, double และอื่น ๆ ), รวมถึง TimeSpan, DateTime, Guid, ทศนิยมและสตริงรวมถึงประเภทใด ๆ ที่มีตัวแปลงประเภทที่สามารถแปลงจากสตริง
สำหรับประเภทที่ซับซ้อน Web API จะพยายามอ่านค่าจากเนื้อหาข้อความโดยใช้ตัวจัดรูปแบบชนิดสื่อ
ดังนั้นหากคุณต้องการแทนที่พฤติกรรมเริ่มต้นข้างต้นและบังคับให้ Web API อ่านประเภทที่ซับซ้อนจาก URI ให้เพิ่ม[FromUri]
แอตทริบิวต์ลงในพารามิเตอร์ หากต้องการบังคับให้ Web API อ่านประเภทอย่างง่ายจากส่วนเนื้อหาคำขอให้เพิ่ม[FromBody]
แอตทริบิวต์เข้ากับพารามิเตอร์
ดังนั้นในการตอบคำถามของคุณความต้องการ[FromBody]
และ[FromUri]
คุณลักษณะใน Web API นั้นเป็นการแทนที่หากจำเป็นพฤติกรรมเริ่มต้นตามที่อธิบายไว้ข้างต้น โปรดทราบว่าคุณสามารถใช้คุณลักษณะทั้งสำหรับวิธีการควบคุม แต่สำหรับพารามิเตอร์ที่แตกต่างกันที่แสดงให้เห็นที่นี่
มีเป็นจำนวนมาก มากขึ้น ข้อมูลบนเว็บถ้าคุณ google "API เว็บพารามิเตอร์ผูกพัน"
JustGetIt
มีจุดประสงค์เดียวกันในการเพิ่มคุณสมบัติหลายอย่างเช่น[FromBody, FromQuery]
อื่น ๆ
พฤติกรรมเริ่มต้นคือ:
ถ้าพารามิเตอร์เป็นดั้งเดิมประเภท ( int
, bool
, double
, ... ), Web API พยายามที่จะได้รับค่าจากURIของคำขอ HTTP
สำหรับประเภทที่ซับซ้อน (เช่นวัตถุของคุณเอง:) Person
Web API พยายามอ่านค่าจากเนื้อความของคำขอ HTTP
ดังนั้นถ้าคุณมี:
... จากนั้นคุณไม่ต้องเพิ่มคุณสมบัติใด ๆ (ไม่ใช่[FromBody]
หรือ[FromUri]
)
แต่ถ้าคุณมีประเภทดั้งเดิมในร่างกายคุณจะต้องเพิ่ม[FromBody]
ด้านหน้าของพารามิเตอร์ประเภทดั้งเดิมในวิธีการควบคุม WebAPI ของคุณ (เนื่องจากโดยค่าเริ่มต้น WebAPI กำลังมองหาประเภทดั้งเดิมใน URI ของคำขอ HTTP)
หรือหากคุณมีประเภทที่ซับซ้อนของคุณในURI[FromUri]
แล้วคุณจะต้องเพิ่ม (เนื่องจากโดยค่าเริ่มต้น WebAPI กำลังค้นหาชนิดที่ซับซ้อนในเนื้อความของคำขอ HTTP โดยค่าเริ่มต้น)
ประเภทดั้งเดิม:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post([FromBody]int id)
{
}
// api/users/id
public HttpResponseMessage Post(int id)
{
}
}
ประเภทที่ซับซ้อน:
public class UsersController : ApiController
{
// api/users
public HttpResponseMessage Post(User user)
{
}
// api/users/user
public HttpResponseMessage Post([FromUri]User user)
{
}
}
สิ่งนี้ใช้ได้ตราบใดที่คุณส่งพารามิเตอร์เดียวในคำขอ HTTP ของคุณ เมื่อส่งหลายรายการคุณต้องสร้างโมเดลที่กำหนดเองซึ่งมีพารามิเตอร์ทั้งหมดของคุณดังนี้:
public class MyModel
{
public string MyProperty { get; set; }
public string MyProperty2 { get; set; }
}
[Route("search")]
[HttpPost]
public async Task<dynamic> Search([FromBody] MyModel model)
{
// model.MyProperty;
// model.MyProperty2;
}
จากเอกสารของ Microsoft สำหรับการผูกพารามิเตอร์ใน ASP.NET Web API :
เมื่อพารามิเตอร์มี [FromBody], Web API จะใช้ส่วนหัว Content-Type เพื่อเลือกฟอร์แมตเตอร์ ในตัวอย่างนี้ประเภทเนื้อหาคือ "application / json" และเนื้อหาคำขอเป็นสตริง JSON แบบดิบ (ไม่ใช่วัตถุ JSON) อย่างน้อยหนึ่งพารามิเตอร์ที่ได้รับอนุญาตให้อ่านจากเนื้อหาของข้อความ
สิ่งนี้น่าจะใช้ได้:
public HttpResponseMessage Post([FromBody] string name) { ... }
สิ่งนี้จะไม่ทำงาน:
// Caution: This won't work! public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
เหตุผลสำหรับกฎนี้คืออาจมีการจัดเก็บเนื้อหาคำขอไว้ในสตรีมที่ไม่มีบัฟเฟอร์ซึ่งสามารถอ่านได้เพียงครั้งเดียว
เพียงเติมคำตอบข้างบน ..
[FromUri] สามารถใช้ในการผูกชนิดที่ซับซ้อนจากพารามิเตอร์ uri แทนการส่งพารามิเตอร์จากการสอบถาม
สำหรับอดีต ..
public class GeoPoint
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
[RoutePrefix("api/Values")]
public ValuesController : ApiController
{
[Route("{Latitude}/{Longitude}")]
public HttpResponseMessage Get([FromUri] GeoPoint location) { ... }
}
สามารถเรียกได้ว่าชอบ:
http://localhost/api/values/47.678558/-122.130989
เมื่อพารามิเตอร์มี [FromBody], Web API จะใช้ส่วนหัว Content-Type เพื่อเลือกฟอร์แมตเตอร์ ในตัวอย่างนี้ประเภทเนื้อหาคือ "application / json" และเนื้อหาคำขอเป็นสตริง JSON แบบดิบ (ไม่ใช่วัตถุ JSON)
อย่างน้อยหนึ่งพารามิเตอร์ที่ได้รับอนุญาตให้อ่านจากเนื้อหาของข้อความ ดังนั้นสิ่งนี้จะไม่ทำงาน:
// Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }
เหตุผลสำหรับกฎนี้คือเนื้อหาของคำขออาจถูกเก็บไว้ในสตรีมที่ไม่มีบัฟเฟอร์ซึ่งสามารถอ่านได้เพียงครั้งเดียว
โปรดไปที่เว็บไซต์เพื่อรับรายละเอียดเพิ่มเติม: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api