วิธีรับการตอบสนอง Json จาก Asp.net (MVC) เพื่อส่งไปยังแอพ Android หรือทุกที่ที่ต้องการรูปแบบ Json ของข้อมูลเซิร์ฟเวอร์ :)
เวลาส่วนใหญ่เราต้องส่งข้อมูลจากเซิร์ฟเวอร์ในรูปแบบ Json เช่นในการส่งข้อมูลจากเซิร์ฟเวอร์โดย Apis ไปยังแอป Android แน่นอนว่าเราต้องการรูปแบบ Json หรือ XML แต่โดยส่วนตัวแล้วฉันใช้ Json เกือบตลอดเวลา (และฉันคิดว่ามันมักจะมากกว่า: ) ))
สำหรับการเข้ารหัส API เราสามารถใช้ภาษาฝั่งเซิร์ฟเวอร์ทั้งหมดเช่น php , asp.net ,... ในบทความนี้ เป้าหมายของฉันคือ Asp.net MVC
ในฐานข้อมูลส่วนใหญ่ เรามีตารางบางตารางที่เชื่อมต่อถึงกัน (one-to-one , one-to-many , many-to-many) หมายความว่าถ้าเราเก็บข้อมูลไว้ในตารางที่เชื่อมต่อถึงกัน แล้วเมื่อไร ดึงบันทึกหนึ่งรายการมา มันมีบันทึกบางอย่างที่เกี่ยวข้องกับตัวมันเอง
ตอนแรกลองจินตนาการว่าเรามีตารางที่ไม่มีความสัมพันธ์กับตารางอื่น ดังนั้นหากเราต้องการรับข้อมูลทั้งหมดนี้ในรูปแบบ Json ก็ทำเหมือนร้อง
List users = db.Users.ToList();
return Json(users, JsonRequestBehavior.AllowGet);
ทีนี้ลองนึกภาพ User table มีความสัมพันธ์กับตารางอื่น ๆ ปัญหาของเราเริ่มต้นจากที่นี่ !!! ทำไม?? เพราะเมื่อเรียบเรียงบรรทัดนี้แล้ว
List users = db.Users.ToList();
เรามีข้อมูลบันทึกของผู้ใช้ทั้งหมด และยังมีข้อมูลที่เกี่ยวข้องกับแต่ละบันทึกของตาราง User ในตารางอื่นด้วย !! ในบางเงื่อนไขก็ดี (บางครั้งเราต้องการบันทึกพิเศษและข้อมูลที่เกี่ยวข้องทั้งหมด) และในบางเงื่อนไขก็แย่เกินไป (บางครั้งเราต้องการเพียงข้อมูลอิสระของตารางโดยไม่มีข้อมูลที่เกี่ยวข้อง)
ทีนี้ถ้าเราใช้ผลตอบแทนแบบนี้
return Json(users, JsonRequestBehavior.AllowGet);
จากนั้นเรามีข้อผิดพลาดที่ระบุว่า A circular reference was detected while serializing an object of type
แล้วเราควรทำอย่างไร? เราสามารถทำบางสิ่งได้ตามความต้องการ !!
หากเราต้องการดึงเขตข้อมูลพิเศษของตารางฐานมา เราก็สามารถทำได้ดังตัวอย่างต่อไปนี้
public JsonResult test()
{
return Json(
(from u in db.Users select new {
name=u.User_Name , family=u.User_Family , location=u.User_location })
, JsonRequestBehavior.AllowGet);
}
หากเราต้องการดึงเขตข้อมูลพิเศษของตารางฐานและตารางที่เกี่ยวข้องกัน เพื่อที่เราจะสามารถทำได้ดังตัวอย่างต่อไปนี้
public JsonResult test()
{
return Json(
db.Users.Select(u => new {
name = u.User_Name, family = u.User_Family, location=u.User_location
,gallery = u.Gallery.Select(g => new {
galleryName=g.Gallery_Name
,galleryDesc=g.Gallery_Desc
})
})
, JsonRequestBehavior.AllowGet);
}
หรือแบบนี้
var gallery = (from u in db.Users
join g in db.Gallery on u.User_ID equals g.Gallery_Admin
where u.User_Email == email && g.Gallery_ID == galleryId
select new
{
Gallery_Name = g.Gallery_Name,
Gallery_Desc = g.Gallery_Desc,
GalleryType = new { GalleryType_ID = g.GalleryType.GalleryType_ID , GalleryType_Title = g.GalleryType.GalleryType_Title, GalleryType_Desc = g.GalleryType.GalleryType_Desc},
Gallery_Time = g.Gallery_Time
}).FirstOrDefault();
หากคุณต้องการดึงข้อมูลทั้งหมดของตารางฐานและบันทึกที่เกี่ยวข้องทั้งหมดในแต่ละตารางด้วย เพื่อให้เราสามารถดำเนินการได้ดังตัวอย่างต่อไปนี้
public ContentResult test()
{
var users = db.Users.ToList();
var list = JsonConvert.SerializeObject(users,
Formatting.None,
new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
return Content(list, "application/json");
}