Как избежать циклической ссылки при сериализации класса 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

Другие вопросы по тегам