Я пытаюсь сделать простой возврат JSON, но у меня возникли проблемы, у меня есть следующие ниже.
public JsonResult GetEventData()
{
var data = Event.Find(x => x.ID != 0);
return Json(data);
}
Я получаю HTTP 500 с исключением, как показано в заголовке этого вопроса. Я тоже пробовал
var data = Event.All().ToList()
Это дало ту же проблему.
Это ошибка или моя реализация?
ScriptIgnore
атрибута. stackoverflow.com/questions/1193857/subsonic-3-0-0-2-structs-ttScriptIgnore
атрибут в свойство Tournament.Game, и он работал нормально :)Ответы:
Кажется, в вашей иерархии объектов есть циклические ссылки, которые не поддерживаются сериализатором JSON. Вам нужны все столбцы? Вы можете выбрать только те свойства, которые вам нужны в представлении:
Это сделает ваш объект JSON легче и легче для понимания. Если у вас много свойств, AutoMapper можно использовать для автоматического сопоставления объектов DTO и объектов View.
источник
У меня была та же проблема, и я решил
using Newtonsoft.Json;
источник
На самом деле это происходит потому, что сложные объекты - это то, что приводит к сбою получающегося объекта json. И это терпит неудачу, потому что, когда объект отображается, он отображает детей, который отображает их родителей, делая круговую ссылку для возникновения. Json потребовалось бы бесконечное время для его сериализации, поэтому это исключает проблему за исключением.
Сопоставление Entity Framework также производит то же поведение, и решение состоит в том, чтобы отбросить все нежелательные свойства.
Просто объясняя окончательный ответ, весь код будет:
Это также может быть следующим, если вы не хотите, чтобы объекты внутри
Result
свойства:источник
Подводя итог, есть 4 решения для этого:
Решение 1: отключите ProxyCreation для DBContext и восстановите его в конце.
Решение 2. Использование JsonConvert путем установки ReferenceLoopHandling для игнорирования настроек сериализатора.
Следующие два решения одинаковы, но лучше использовать модель, потому что она строго типизирована.
Решение 3: вернуть модель, которая включает только необходимые свойства.
Решение 4: вернуть новый динамический объект, который включает только необходимые свойства.
источник
JSON, как и XML и другие форматы, является форматом сериализации на основе дерева. Он не будет любить вас, если у вас есть круговые ссылки в ваших объектах, так как «дерево» будет:
Часто есть способы отключить навигацию по определенному пути; Например,
XmlSerializer
вы можете пометить родительское свойство какXmlIgnore
. Я не знаю, возможно ли это с рассматриваемым сериализатором json, иDatabaseColumn
есть ли у него подходящие маркеры ( очень маловероятно, поскольку он должен ссылаться на каждый API сериализации)источник
Это из-за нового шаблона DbContext T4, который используется для генерации сущностей EntityFramework. Чтобы иметь возможность выполнять отслеживание изменений, в этих шаблонах используется шаблон Proxy, заключая в них ваши красивые POCO. Это тогда вызывает проблемы при сериализации с JavaScriptSerializer.
Итак, 2 решения:
Вы можете отключить автоматическую генерацию прокси, установив его в настройках контекста.
context.Configuration.ProxyCreationEnabled = false;
Очень хорошо объяснено в статье ниже.
http://juristr.com/blog/2011/08/javascriptserializer-circular-reference/
источник
Использование Newtonsoft.Json: в вашем методе Global.asax Application_Start добавьте эту строку:
источник
добавить
[JsonIgnore]
к виртуальным свойствам в вашей модели.источник
Избегайте преобразования объекта таблицы напрямую. Если отношения установлены между другими таблицами, это может вызвать эту ошибку. Скорее вы можете создать класс модели, присвоить значения объекту класса и затем сериализовать его.
источник
Предоставленные ответы хороши, но я думаю, что их можно улучшить, добавив «архитектурную» перспективу.
изучение
MVC's Controller.Json
функция выполняет свою работу, но в этом случае она очень слаба для предоставления соответствующей ошибки. При использованииNewtonsoft.Json.JsonConvert.SerializeObject
ошибка точно указывает, какое именно свойство вызывает циклическую ссылку. Это особенно полезно при сериализации более сложных иерархий объектов.Правильная архитектура
Никогда не следует пытаться сериализовать модели данных (например, модели EF), поскольку навигационные свойства ORM - это путь к гибели, когда дело доходит до сериализации. Поток данных должен быть следующим:
Сервисные модели могут быть получены из моделей данных с использованием автоматических картографов (например, Automapper ). Хотя это не гарантирует отсутствие циклических ссылок, надлежащий дизайн должен это делать: модели сервиса должны содержать именно то, что требуется потребителю сервиса (то есть свойства).
В тех редких случаях, когда клиент запрашивает иерархию, включающую один и тот же тип объекта на разных уровнях, служба может создать линейную структуру с родительскими и дочерними отношениями (используя только идентификаторы, а не ссылки).
Современные приложения имеют тенденцию избегать загрузки сложных структур данных сразу, а сервисные модели должны быть тонкими. Например:
источник
Я использую исправление, потому что использую Knockout в представлениях MVC5.
На действии
функция
источник
Вы можете заметить свойства, которые вызывают круговую ссылку. Тогда вы можете сделать что-то вроде:
источник
источник
Более простой альтернативой для решения этой проблемы является возврат строки и форматирование этой строки в json с помощью JavaScriptSerializer.
Важно, чтобы «Выбрать» часть, которая выбирает свойства, которые вы хотите в вашем представлении. У некоторого объекта есть ссылка на родителя. Если вы не выберете атрибуты, может появиться циклическая ссылка, если вы просто возьмете таблицы в целом.
Не делай этого:
Сделайте это вместо этого, если вы не хотите всю таблицу:
Это помогает отображать представление с меньшим количеством данных, просто с необходимыми атрибутами, и ускоряет работу вашей сети.
источник