خیلی وقتها لازم است تا نتیجه کوئری حاصله را بصورت Json به ویوی مورد نظر ارسال نمایید. برای اینکار کافیست مانند زیر عمل کنیم
[HttpGet]
public JsonResult Get(int id)
{
return Json(repository.Find(id), JsonRequestBehavior.AllowGet);
}
اما اگر کوئری پیچیده و یا یک
مدل سلسله مراتبی داشته باشید که با خودش کلید خارجی داشته باشد، هنگام تبدیل نتایج به خروجی Json، با خطای Circular References مواجه میشوید.
A circular reference was detected while serializing an object of type ‘System.Data.Entity.DynamicProxies.ItemCategory_A79…’
علت این مشکل این است که Json Serialization پش فرض ASP.NET MVC فقط یک سطح پایینتر را لود میکند و در مدلهای که خاصیتی از نوع خودشان داشته باشند خطای Circular References را فرا میخواند. کلاس نمونه در زیر آوره شده است.
public class Item
{
public int Id { get; set; }
[ForeignKey]
public int ItemId { get; set; }
public string Name { get; set; }
public ICollection<Item> Items { get; set; }
}
راه حل:
چندین راه حل برای رفع این خطا وجود دارد؛ یکی استفاده از
Automapper و راه حل دیگر استفاده از کتابخانههایهای قویتر کار بار Json مثل
Json.net است. اما راه حل سادهتر تبدیل خروجی کوئری به یک شی بی نام و سپس تبدیل به Json میباشد
[HttpGet]
public JsonResult List()
{
var data = repository.AllIncluding(itemcategory => itemcategory.Items);
var collection = data.Select(x => new
{
id = x.Id,
name = x.Name,
items = x.Items.Select(item => new
{
id=item.Id,
name = item.Name
})
});
return Json(collection, JsonRequestBehavior.AllowGet);
}
همین طور که در مثال بالا مشاهده مینمایید ابتدا همه رکوردها در متغییر data ریخته شده و سپس با یک کوئری دیگر که در آن دوباره از پروپرتی items که از نوع کلاس item میباشد شی بی نامی ایجاد نموده ایم. با این کار براحتی این خطا رفع میگردد.