ASP.NET MVC JSON поверх свободно используемой модели Nhibernate - PullRequest
3 голосов
/ 12 июля 2011

Я пытаюсь вернуть JsonResult, используя стандартный метод контроллера MVC Json(object). Мой объект типа Model1 создан Fluent NHibernate.

Model1 имеет свойство типа Model2. В режиме отладки я вижу, что среда создает класс-потомок прокси Model2 с именем Castle.Proxies.Model2Proxy. Я считаю, что это используется внутри Fluent Nhibernate для удовлетворения моих отображений. А во время выполнения фактическая модель1.Model2 имеет тип Castle.Proxies.Model2Proxy.

Проблема в том, что, когда мой Model1 сериализуется, Model2 тоже сериализуется. И сериализатор, кажется, пытается сериализовать все свойства этого объекта, включая те, которые были сгенерированы Каслом и не нужны мне. Я был бы в порядке с этим, если бы это не вызвало исключение. А именно, где-то внутри этого объекта представлена ​​круговая ссылка, и этим вызвано исключение. Вот текст исключения:

System.InvalidOperationException: A circular reference was detected while serializing an object of type 'System.Reflection.RuntimeModule'

Я дважды проверил свой домен и не нашел там циркулярных ссылок, поэтому я обвиняю Касла. Я прав? Действительно ли Касл виноват в этом? Если да, то какие у меня варианты? Как сказать сериализатору игнорировать свойства Замка? В частности, как мне сказать ему сериализовать определенный тип, а не фактический один?

Я стремлюсь покрыть свои доменные модели с помощью ViewModels для решения этой проблемы, что является рекомендуемым подходом, но я бы очень хотел узнать другое лекарство, если оно существует.

1 Ответ

2 голосов
/ 13 июля 2011

в общем случае не рекомендуется сериализовать объекты модели.
это потому, что вы хотите иметь полный контроль над тем, что вы сериализируете и отправляете клиенту.
при сериализации объектов модели вы можетесериализовать весь связанный с ними объектный граф, который вам необязательно / нужен.
(например, если вы хотите, чтобы пользователь просматривал только сущность Model1, возможно, вы отправляете также Model2 entity, вместе с Model3 коллекцией и т. д.)

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

public class Model1DTO
{
   public int Id;
   public string Name;
   public string Model2Name;
   //whatever other properties you need to display
}
...