Feeds:
Posts
Comments

Archive for the ‘JSON’ Category

I use NHibernate with Json.NET and noticed that I was getting inexplicable “__interceptors” properties in my serialized objects. A google search turned up this excellent solution by Lee Henson which I adapted to work with Json.NET 3.5 Release 5 as follows.

    public class NHibernateContractResolver : DefaultContractResolver
    {
      private static readonly MemberInfo[] NHibernateProxyInterfaceMembers = typeof(INHibernateProxy).GetMembers();

      protected override List<MemberInfo> GetSerializableMembers(Type objectType)
      {
        var members = base.GetSerializableMembers(objectType);

        members.RemoveAll(memberInfo =>
                          (IsMemberPartOfNHibernateProxyInterface(memberInfo)) ||
                          (IsMemberDynamicProxyMixin(memberInfo)) ||
                          (IsMemberMarkedWithIgnoreAttribute(memberInfo, objectType)) ||
                          (IsMemberInheritedFromProxySuperclass(memberInfo, objectType)));

        var actualMemberInfos = new List<MemberInfo>();

        foreach (var memberInfo in members)
        {
          var infos = memberInfo.DeclaringType.BaseType.GetMember(memberInfo.Name);
          actualMemberInfos.Add(infos.Length == 0 ? memberInfo : infos[0]);
        }

        return actualMemberInfos;
      }

      private static bool IsMemberDynamicProxyMixin(MemberInfo memberInfo)
      {
        return memberInfo.Name == "__interceptors";
      }

      private static bool IsMemberInheritedFromProxySuperclass(MemberInfo memberInfo, Type objectType)
      {
        return memberInfo.DeclaringType.Assembly == typeof(INHibernateProxy).Assembly;
      }

      private static bool IsMemberMarkedWithIgnoreAttribute(MemberInfo memberInfo, Type objectType)
      {
        var infos = typeof(INHibernateProxy).IsAssignableFrom(objectType)
                      ? objectType.BaseType.GetMember(memberInfo.Name)
                      : objectType.GetMember(memberInfo.Name);

        return infos[0].GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Length > 0;
      }

      private static bool IsMemberPartOfNHibernateProxyInterface(MemberInfo memberInfo)
      {
        return Array.Exists(NHibernateProxyInterfaceMembers, mi => memberInfo.Name == mi.Name);
      }
    }

To use it just put an instance in the ContractResolver property of your JsonSerializer. The circular dependency problem noted by jishi can be resolved by setting the ReferenceLoopHandling property to ReferenceLoopHandling.Ignore . Here’s an extension method that can be used to serialize objects using Json.Net

      public static void SerializeToJsonFile<T>(this T itemToSerialize, string filePath)
      {
        using (StreamWriter streamWriter = new StreamWriter(filePath))
        {
          using (JsonWriter jsonWriter = new JsonTextWriter(streamWriter))
          {
            jsonWriter.Formatting = Formatting.Indented;
            JsonSerializer serializer = new JsonSerializer
              {
                NullValueHandling = NullValueHandling.Ignore,
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
                ContractResolver = new NHibernateContractResolver(),
              };
            serializer.Serialize(jsonWriter, itemToSerialize);
          }
        }
      }

History

Read Full Post »

%d bloggers like this: