Declan McNulty
Declan McNulty

Reputation: 3374

JsonSerializationException on lazy loaded nHibernate object in WebApi when called from Angularjs service

I am calling a WebApi controller Get method from an Angularjs service.

The angular service:

app.service('MyService', ['$http', function ($http) {

    var getMyObjects = function () {
        var myObjects;
        var promise = $http.get('/api/objects/').success(function (data) {
            myObjects = data;
         }).error(function (data, status, headers, config) {

         });

         return promise;
    };

    return {
        myObjects: myObjects
    };
}]);

The WebApi Get method:

public class ObjectsController : ApiController
{
    public IEnumerable<MyObject> Get()
    {
        return _objectRepository.GetAll().ToArray();
    }
}

I am getting a 500 server error on the client, the inner exception of which is:

ExceptionMessage: "Error getting value from 'IdentityEqualityComparer' on 
'NHibernate.Proxy.DefaultLazyInitializer'."
ExceptionType: "Newtonsoft.Json.JsonSerializationException"

What should I do to resolve this issue?

EDIT: I resolved the above exception by adding the following one liner to WebApiConfig.cs as per this answer:

((DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.
                           ContractResolver).IgnoreSerializableAttribute = true;

Now I have this exception:

ExceptionMessage: "Error getting value from 'DefaultValue'
on 'NHibernate.Type.DateTimeOffsetType'."
ExceptionType: "Newtonsoft.Json.JsonSerializationException"

Any ideas on if there is something similar I can do to fix this?

Upvotes: 4

Views: 5270

Answers (2)

Declan McNulty
Declan McNulty

Reputation: 3374

Based on this answer and this answer, I have fixed the issue by adding the following class

public class NHibernateContractResolver : DefaultContractResolver
{
   protected override JsonContract CreateContract(Type objectType) 
   {
      if (typeof(NHibernate.Proxy.INHibernateProxy).IsAssignableFrom(objectType))
          return base.CreateContract(objectType.BaseType);

        return base.CreateContract(objectType);
    }
}

and then setting it as the contract resolver in Application_Start in Global.asax.cs:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings
                            .ContractResolver = new NHibernateContractResolver();

Upvotes: 10

fed.pavlo
fed.pavlo

Reputation: 245

Eager loading is worth having whole DB crash. Lazy load prevents you from loading unnecessary referenced data. But also you must ensure that you have pointed hibernate which references to load.

But your exception is thrown because of Serialization issue

Upvotes: 0

Related Questions