Как избежать циклической ссылки при сериализации класса Entity Framework
У меня есть приложение MVC-3 (RC1), использующее Entity Framework 4.
Я хочу вернуть объект JSON из действия контроллера. На этот объект ссылаются другие объекты, которые, очевидно, возвращают ссылку.
Таким образом я получаю следующую ошибку циклической ссылки:
Ошибка сервера в приложении '/'
При сериализации объекта типа "Application.Models.ReferenceObject" была обнаружена циклическая ссылка.
Описание: во время выполнения текущего веб-запроса произошло необработанное исключение. Пожалуйста, просмотрите трассировку стека для получения дополнительной информации об ошибке и о том, где она возникла в коде.
Сведения об исключении: System.InvalidOperationException: при сериализации объекта типа "Application.Models.ReferenceObject" была обнаружена циклическая ссылка.
NB: Application & ReferenceObject, очевидно, являются заменами для реального пространства имен / объекта.
В соответствии с исключением переполнения стека: циклическая ссылка при сериализации классов LINQ to SQL, это можно преодолеть с помощью JSON.Net; однако я хотел бы избежать этого и вместо этого попытаться исключить ошибочные ссылочные свойства из сериализуемого объекта.
Что я имею в виду?
Я хочу сделать что-то вроде этого:
IList<ReferenceObject> list = Repository.GetReferenceObjects();
return Json(list.**<method>**("ObjectsReferencingThis"));
где **<method>**
это какой-то метод, который делает противоположное ObjectQuery(Of T).Include
метод и ObjectsReferencingThis
это свойство, которое вызывает циклическую ссылку.
NB. Я не хочу удалять эти свойства или создавать POCO, поскольку это влияет только на сериализацию Json.
Кто-нибудь может помочь, пожалуйста?
:)
2 ответа
У меня была похожая проблема, когда я работал над одним из моих предыдущих проектов. Вот что я в итоге сделал:
IList<Product> list = Repository.GetProducts();
var collection = products.Select(product => new
{
id = product.Id,
name = product.Name,
detailUrl = product.DetailUrl,
imageLargeUrl = product.ThumbNailUrl,
tagtitle = product.Name.ToUpper(),
tagheader = "Words our cherished patrons use to describe this product",
tagwords = from tag in product.Tags group tag by tag.Name into words select new { name = words.Key, weight = words.Count() }
});
var result = new {id = inquiry.Id, products = collection, };
return this.Jsonp(result);
Вот как будет выглядеть результат Json:
{
"id" : 2,
"products" : [{
"id" : "3605970008857",
"name" : "TITLE1",
"detailUrl" : "http://www.urlhere.com",
"tagwords" : [{
"name" : "roses",
"weight" : 1
},
{
"name" : "cotton",
"weight" : 1
},
{
"name" : "happy",
"weight" : 1
}]
},
{
"id" : "3605970019891",
"name" : "TITLE2",
"detailUrl" : "http://www.urlhere.com",
"tagwords" : []
}],
}
Вы также можете добавить любые другие свойства объектов, на которые вы ссылаетесь, к результату, как вы хотите, чтобы они отображались в вашем объекте Json:)
Я сделал очень тривиальное решение, которое не рекомендуется, если у вас очень большой список
letters=UserOperations.GetDepartmentLettersForSecretary(pageNumber, pageSize,(Session["User"] as User).DepartmentID.Value, (Session["User"] as User).ID);
foreach (Letter letter in letters)
{
letter.LetterStatus.Letters = null;
}
проблема circular reference
в моем случае это в LetterStatus.Letters, поэтому я Iterated through the list
а также assigned it to null
как я уже говорил not recommended
если у вас есть very big list