При сериализации объекта типа SubSonic.Schema .DatabaseColumn была обнаружена циклическая ссылка. - PullRequest
166 голосов
/ 20 июля 2009

Я пытаюсь выполнить простое возвращение JSON, но у меня возникли проблемы, у меня есть следующее ниже.

public JsonResult GetEventData()
{
    var data = Event.Find(x => x.ID != 0);
    return Json(data);
}

Я получаю HTTP 500 с исключением, как показано в заголовке этого вопроса. Я тоже пробовал

var data = Event.All().ToList()

Это дало ту же проблему.

Это ошибка или моя реализация?

Ответы [ 14 ]

1 голос
/ 14 сентября 2014

Я использую исправление, потому что использую Knockout в представлениях MVC5.

В действии

return Json(ModelHelper.GetJsonModel<Core_User>(viewModel));

функция

   public static TEntity GetJsonModel<TEntity>(TEntity Entity) where TEntity : class
    {
        TEntity Entity_ = Activator.CreateInstance(typeof(TEntity)) as TEntity;
        foreach (var item in Entity.GetType().GetProperties())
        {
            if (item.PropertyType.ToString().IndexOf("Generic.ICollection") == -1 && item.PropertyType.ToString().IndexOf("SaymenCore.DAL.") == -1)
                item.SetValue(Entity_, Entity.GetPropValue(item.Name));
        }
        return Entity_;  
    }
0 голосов
/ 30 августа 2017

Более простой альтернативой для решения этой проблемы является возврат строки и форматирование этой строки в json с помощью JavaScriptSerializer.

public string GetEntityInJson()
{
   JavaScriptSerializer j = new JavaScriptSerializer();
   var entityList = dataContext.Entitites.Select(x => new { ID = x.ID, AnotherAttribute = x.AnotherAttribute });
   return j.Serialize(entityList );
}

Очень важна часть «Выбор», которая выбирает свойства, которые вы хотите видеть. У некоторого объекта есть ссылка на родителя. Если вы не выберете атрибуты, может появиться циклическая ссылка, если вы просто возьмете таблицы в целом.

Не делайте этого:

public string GetEntityInJson()
{
   JavaScriptSerializer j = new JavaScriptSerializer();
   var entityList = dataContext.Entitites.toList();
   return j.Serialize(entityList );
}

Сделайте это вместо этого, если вы не хотите всю таблицу:

public string GetEntityInJson()
{
   JavaScriptSerializer j = new JavaScriptSerializer();
   var entityList = dataContext.Entitites.Select(x => new { ID = x.ID, AnotherAttribute = x.AnotherAttribute });
   return j.Serialize(entityList );
}

Это помогает визуализировать представление с меньшим количеством данных, просто с необходимыми атрибутами, и ускоряет работу сети.

0 голосов
/ 21 декабря 2016

Вы можете заметить свойства, которые вызывают круговую ссылку. Тогда вы можете сделать что-то вроде:

private Object DeCircular(Object object)
{
   // Set properties that cause the circular reference to null

   return object
}
0 голосов
/ 24 февраля 2015
//first: Create a class as your view model

public class EventViewModel 
{
 public int Id{get;set}
 public string Property1{get;set;}
 public string Property2{get;set;}
}
//then from your method
[HttpGet]
public async Task<ActionResult> GetEvent()
{
 var events = await db.Event.Find(x => x.ID != 0);
 List<EventViewModel> model = events.Select(event => new EventViewModel(){
 Id = event.Id,
 Property1 = event.Property1,
 Property1 = event.Property2
}).ToList();
 return Json(new{ data = model }, JsonRequestBehavior.AllowGet);
}
...