1

I cannot serialize then immediately deserialize a large object without issues. I followed advice from: JSON.NET and nHibernate Lazy Loading of Collections and JSON.Net Serialization of NHibernate Proxies (NH 3.3.2.4000) to get Json.Net working with my legacy system. Despite trying the suggestions and in various combinations i have had no success. Here are the settings that make most sense to me as i understand them all.

Converter:

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

Main Code:

    var jsonSerializerSettings = new JsonSerializerSettings
    {
        ContractResolver = new NHibernateContractResolver(),
        PreserveReferencesHandling = PreserveReferencesHandling.All,
        TypeNameHandling = TypeNameHandling.Auto,
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
        ObjectCreationHandling = ObjectCreationHandling.Replace
    };

    string serialisedEnquiry = JsonConvert.SerializeObject(enquiry, Formatting.Indented, jsonSerializerSettings);

    Enquiry enq = JsonConvert.DeserializeObject<Enquiry>(serialisedEnquiry, jsonSerializerSettings);

I have another SO question open which may be of note: JSON.net null property Although as you will see in the last comment, i believe i have solved it. I am just waiting to solve this problem to confirm the other is fixed and not simply buried/replaced by this new error.

Fluent NHibernate 1.4.0.0

NHibernate 3.3.1.4000

Netwonsoft.Json 6.0.0.0

EDIT:

My exception is:

An unhandled exception of type 'NHibernate.LazyInitializationException' occurred in Newtonsoft.Json.dll

Additional information: Initializing[Unavailable#]-failed to lazily initialize a collection, no session or session was closed

I have actually found this buried within my JSON:

$type : "NHibernate.Collection.Generic.PersistentGenericBag`1[[ComponentModel.Role, ComponentModel]], NHibernate"

I am not sure why when i have the NHibernate converter but it gives me a lead i can look into. I will post back if i find anything.

7
  • It's too little details in your question to figure out the issue. Could you publish exception details? Commented Jun 10, 2014 at 8:27
  • Hi Mikalai. Coincidentally i just go back to this issue today and was able to find out a bit more - see my edit. I am hoping my converter just needs to be tweaked somehow to take care of the collection that i guess is being parsed from the NHibernate proxy. Commented Jun 10, 2014 at 9:18
  • I have a feeling in the guts that you're doing something dangerous... What is the code for NHibernateContractResolver? Commented Jun 10, 2014 at 12:25
  • Actually I think that's essentially not correct - you should have good understanding of what NH does behind the scene. There is no easy way to avoid lazy loading as well. I have a proposal which would always work, but has its price. The way is: you create a 'model' classes and map your 'data' classes to them (using Automapper for example). Then you serialize 'model' classes with ease. And you have total control over their internals and wouldn't encounter such issues in future or will be able to fix them easily. Commented Jun 10, 2014 at 12:39
  • If i understand you right, i was actually considering doing this earlier but thought it was bad practice - i.e a needless step. However, i am still unsure. If i force load all my collections before parsing, should it not work as planned? In fact is that not essentially what your model idea would be doing anyway? Or do you believe the key lies in stripping away the behavior to have a data only object? p.s My first code snippet is my NHibernateContractResolver Commented Jun 10, 2014 at 13:42

1 Answer 1

5

I never found out exactly what was wrong but i happened across this configuration when i was playing with it and it worked.

    jsonSerializerSettings = new JsonSerializerSettings()
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
        PreserveReferencesHandling = PreserveReferencesHandling.Objects,
        ContractResolver = new NHibernateContractResolver(),
        NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
        TypeNameHandling = TypeNameHandling.Objects,
        //TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple,
        ObjectCreationHandling = ObjectCreationHandling.Replace
    };

NHibernateContractResolver class:

public class NHibernateContractResolver : DefaultContractResolver
{
    protected override JsonContract CreateContract(Type objectType)
    {
        if (typeof(INHibernateProxy).IsAssignableFrom(objectType))
            return base.CreateContract(objectType.BaseType);
        else
            return base.CreateContract(objectType);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I don't see a need for ObjectCreationHandling = ObjectCreationHandling.Replace ObjectCreationHandling.Auto might be better, but this saved me a ton of time. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.