Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON.NET and nHibernate Lazy Loading of Collections

Is anybody using JSON.NET with nHibernate? I notice that I am getting errors when I try to load a class with child collections.

like image 892
user32326 Avatar asked Nov 13 '08 10:11

user32326


2 Answers

I was facing the same problem so I tried to use @Liedman's code but the GetSerializableMembers() was never get called for the proxied reference. I found another method to override:

  public class NHibernateContractResolver : DefaultContractResolver   {       protected override JsonContract CreateContract(Type objectType)       {           if (typeof(NHibernate.Proxy.INHibernateProxy).IsAssignableFrom(objectType))               return base.CreateContract(objectType.BaseType);           else               return base.CreateContract(objectType);       }   } 
like image 142
Alireza Sabouri Avatar answered Sep 28 '22 03:09

Alireza Sabouri


We had this exact problem, which was solved with inspiration from Handcraftsman's response here.

The problem arises from JSON.NET being confused about how to serialize NHibernate's proxy classes. Solution: serialize the proxy instances like their base class.

A simplified version of Handcraftsman's code goes like this:

public class NHibernateContractResolver : DefaultContractResolver {     protected override List<MemberInfo> GetSerializableMembers(Type objectType) {         if (typeof(INHibernateProxy).IsAssignableFrom(objectType)) {             return base.GetSerializableMembers(objectType.BaseType);         } else {             return base.GetSerializableMembers(objectType);         }     } } 

IMHO, this code has the advantage of still relying on JSON.NET's default behaviour regarding custom attributes, etc. (and the code is a lot shorter!).

It is used like this

        var serializer = new JsonSerializer{             ReferenceLoopHandling = ReferenceLoopHandling.Ignore,             ContractResolver = new NHibernateContractResolver()         };         StringWriter stringWriter = new StringWriter();         JsonWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(stringWriter);                         serializer.Serialize(jsonWriter, objectToSerialize);         string serializedObject = stringWriter.ToString(); 

Note: This code was written for and used with NHibernate 2.1. As some commenters have pointed out, it doesn't work out of the box with later versions of NHibernate, you will have to make some adjustments. I will try to update the code if I ever have to do it with later versions of NHibernate.

like image 26
Liedman Avatar answered Sep 28 '22 03:09

Liedman