รุ่นพื้นฐานที่สุดที่ตอบสนองด้วย a JsonResult
คือ:
// GET: api/authors
[HttpGet]
public JsonResult Get()
{
return Json(_authorRepository.List());
}
อย่างไรก็ตามสิ่งนี้จะไม่ช่วยแก้ไขปัญหาของคุณเนื่องจากคุณไม่สามารถจัดการกับรหัสการตอบสนองของคุณเองได้อย่างชัดเจน
วิธีที่จะได้รับผลการควบคุมสถานะคือคุณต้องกลับมาActionResult
ซึ่งเป็นที่ที่คุณสามารถใช้ประโยชน์จากStatusCodeResult
ประเภท
ตัวอย่างเช่น:
// GET: api/authors/search?namelike=foo
[HttpGet("Search")]
public IActionResult Search(string namelike)
{
var result = _authorRepository.GetByNameSubstring(namelike);
if (!result.Any())
{
return NotFound(namelike);
}
return Ok(result);
}
หมายเหตุทั้งสองตัวอย่างข้างต้นมาจากคำแนะนำที่ดีจากเอกสารของ Microsoft: การจัดรูปแบบข้อมูลการตอบสนอง
สิ่งพิเศษ
ปัญหาที่ฉันเจอบ่อยๆคือฉันต้องการการควบคุม WebAPI ที่ละเอียดยิ่งขึ้นแทนที่จะไปกับการกำหนดค่าเริ่มต้นจากแม่แบบ "โครงการใหม่" ใน VS
มาทำให้แน่ใจว่าคุณมีพื้นฐานบางอย่างอยู่ ...
ขั้นตอนที่ 1: กำหนดค่าบริการของคุณ
เพื่อให้ ASP.NET Core WebAPI ของคุณตอบสนองกับ JSON Serialized Object พร้อมการควบคุมรหัสสถานะอย่างสมบูรณ์คุณควรเริ่มต้นด้วยการทำให้แน่ใจว่าคุณได้รวมAddMvc()
บริการในConfigureServices
วิธีการของคุณตามปกติStartup.cs
แล้ว
สิ่งสำคัญคือให้สังเกตว่าAddMvc()
จะรวมฟอร์แมตอินพุต / เอาต์พุตสำหรับ JSON โดยอัตโนมัติพร้อมกับการตอบสนองต่อคำขอประเภทอื่น
หากโครงการของคุณต้องการการควบคุมเต็มรูปแบบและคุณต้องการกำหนดบริการของคุณอย่างเคร่งครัดเช่นวิธีที่ WebAPI ของคุณจะทำงานกับประเภทคำขอต่างๆรวมถึงapplication/json
และไม่ตอบสนองต่อคำขอประเภทอื่น ๆ (เช่นคำขอเบราว์เซอร์มาตรฐาน) คุณสามารถกำหนดด้วยตนเอง รหัสต่อไปนี้:
public void ConfigureServices(IServiceCollection services)
{
// Build a customized MVC implementation, without using the default AddMvc(), instead use AddMvcCore().
// https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNetCore.Mvc/MvcServiceCollectionExtensions.cs
services
.AddMvcCore(options =>
{
options.RequireHttpsPermanent = true; // does not affect api requests
options.RespectBrowserAcceptHeader = true; // false by default
//options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
//remove these two below, but added so you know where to place them...
options.OutputFormatters.Add(new YourCustomOutputFormatter());
options.InputFormatters.Add(new YourCustomInputFormatter());
})
//.AddApiExplorer()
//.AddAuthorization()
.AddFormatterMappings()
//.AddCacheTagHelper()
//.AddDataAnnotations()
//.AddCors()
.AddJsonFormatters(); // JSON, or you can build your own custom one (above)
}
คุณจะสังเกตเห็นว่าฉันได้รวมวิธีการในการเพิ่มตัวจัดรูปแบบอินพุต / เอาท์พุตของคุณเองในกรณีที่คุณอาจต้องการตอบสนองต่อรูปแบบการจัดลำดับอื่น ๆ (protobuf, thrift, ฯลฯ )
อันของรหัสข้างต้นส่วนใหญ่จะซ้ำกันของAddMvc()
วิธีการ อย่างไรก็ตามเรากำลังดำเนินการบริการ "เริ่มต้น" แต่ละรายการด้วยตัวเราเองโดยกำหนดบริการแต่ละรายการแทนการไปกับเทมเพลตที่จัดส่งล่วงหน้าไว้ล่วงหน้า ฉันได้เพิ่มลิงก์ที่เก็บในบล็อคโค้ดหรือคุณสามารถเช็คเอาท์AddMvc()
จากที่เก็บ GitHub .
โปรดทราบว่ามีคำแนะนำบางอย่างที่จะพยายามแก้ปัญหานี้โดย "เลิกทำ" ค่าเริ่มต้นแทนที่จะไม่นำมาใช้ในตอนแรก ... หากคุณพิจารณาว่าตอนนี้เรากำลังทำงานกับ Open Source นี่เป็นงานซ้ำซ้อน รหัสไม่ดีและนิสัยเก่าตรงไปตรงมาที่จะหายไปในไม่ช้า
ขั้นตอนที่ 2: สร้างตัวควบคุม
ฉันจะแสดงให้คุณเห็นคำถามที่ตรงไปตรงมาเพียงเพื่อให้คุณเรียงลำดับคำถามของคุณ
public class FooController
{
[HttpPost]
public async Task<IActionResult> Create([FromBody] Object item)
{
if (item == null) return BadRequest();
var newItem = new Object(); // create the object to return
if (newItem != null) return Ok(newItem);
else return NotFound();
}
}
ขั้นตอนที่ 3: ตรวจสอบของคุณContent-Type
และAccept
คุณต้องตรวจสอบให้แน่ใจว่าได้ตั้งค่าส่วนหัวContent-Type
และAccept
ส่วนหัวในคำขออย่างถูกต้อง ในกรณีของคุณ (JSON) application/json
คุณจะต้องการที่จะตั้งขึ้นเพื่อเป็น
หากคุณต้องการ WebAPI ของคุณเพื่อตอบสนองเป็น JSON เป็นค่าเริ่มต้นโดยไม่คำนึงถึงสิ่งที่ส่วนหัวของคำขอจะระบุที่คุณสามารถทำได้ในสองวิธี
วิธีที่ 1
ดังที่แสดงในบทความที่ฉันแนะนำไว้ก่อนหน้านี้ ( การจัดรูปแบบข้อมูลการตอบสนอง ) คุณสามารถบังคับรูปแบบเฉพาะที่ระดับตัวควบคุม / การดำเนินการ ฉันเองไม่ชอบวิธีการนี้ ... แต่ที่นี่มีไว้สำหรับความสมบูรณ์:
การบังคับใช้รูปแบบเฉพาะหากคุณต้องการ จำกัด รูปแบบการตอบกลับสำหรับการกระทำเฉพาะที่คุณสามารถทำได้คุณสามารถใช้ตัวกรอง [ผลิต] ตัวกรอง [ผลิต] ระบุรูปแบบการตอบกลับสำหรับการดำเนินการเฉพาะ (หรือตัวควบคุม) เช่นเดียวกับตัวกรองส่วนใหญ่สามารถใช้กับการกระทำตัวควบคุมหรือขอบเขตส่วนกลาง
[Produces("application/json")]
public class AuthorsController
[Produces]
กรองจะบังคับให้การดำเนินการทั้งหมดภายใน
AuthorsController
ที่จะกลับมาตอบสนองรูปแบบ JSON แม้ว่า formatters อื่น ๆ ที่ถูกกำหนดค่าสำหรับการประยุกต์ใช้และลูกค้าให้Accept
ส่วนหัวขอที่แตกต่างกัน, รูปแบบที่มีอยู่
วิธีที่ 2 วิธีที่
ฉันชอบคือให้ WebAPI ตอบกลับคำขอทั้งหมดด้วยรูปแบบที่ร้องขอ อย่างไรก็ตามในกรณีที่มันไม่ยอมรับรูปแบบที่ร้องขอแล้วเลื่อนกลับไปที่ค่าเริ่มต้น (เช่น. JSON)
ก่อนอื่นคุณจะต้องลงทะเบียนในตัวเลือกของคุณ (เราจำเป็นต้องทำงานซ้ำพฤติกรรมเริ่มต้นตามที่ระบุไว้ก่อนหน้านี้)
options.RespectBrowserAcceptHeader = true; // false by default
ในที่สุดเพียงแค่สั่งรายการตัวจัดรูปแบบที่กำหนดไว้ในตัวสร้างบริการอีกครั้งเว็บโฮสต์จะใช้ค่าเริ่มต้นเป็นฟอร์แมตเตอร์ที่คุณวางไว้ที่ด้านบนของรายการ (เช่นตำแหน่ง 0)
ข้อมูลเพิ่มเติมสามารถพบได้ในรายการ. NET Web Development และ Tools Blog
CreatedAtRoute
วิธีการอื่น ๆ