Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 827
Declan McNulty Avatar asked Dec 26 '22 06:12

Declan McNulty


1 Answers

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();
like image 85
Declan McNulty Avatar answered Mar 02 '23 01:03

Declan McNulty