2

When the Json.Net typenamehandling is set to Object, anonymous objects can have very long typenames for example:

_IB_8bgoVaqDaVjOpT0PxYDBjiO_pwOo[[System.Guid, mscorlib],[System.Nullable`1[[System.Guid, mscorlib]], mscorlib],[System.String, mscorlib],[System.String, mscorlib],[System.String, mscorlib],[System.String, mscorlib],[System.String, mscorlib],[System.String, mscorlib],[System.Nullable`1[[System.Int32, mscorlib]], mscorlib],[System.Nullable`1[[System.Int32, mscorlib]], mscorlib],[System.Nullable`1[[System.Int32, mscorlib]], mscorlib],[System.String, mscorlib]], _IB_8bgoVaqDaVjOpT0PxYDBjiO_pwOo_IdeaBlade

Is there any setting I can tweak to reduce that size?

Jacob Eggers
  • 9,062
  • 2
  • 25
  • 43
  • Why are using anonymous objects? When using `typenamehandling = TypeNameHandling.All` it anyway won't make any sense because JSon.net cannot use the information of deseriazliation and won't create anonymous types for you... – nemesv Mar 04 '15 at 20:11
  • @nemesv They are mappings of typed objects, and can contain full typed objects in their properties. So we do in fact need them. – Jacob Eggers Mar 05 '15 at 08:29

1 Answers1

2

Create your own SerializationBinder derived from DefaultSerializationBinder.

Override BindToName (default code below) with your own logic for anonymous types (the default implementation is below):

public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
#if NETFX_CORE || PORTABLE
        assemblyName = serializedType.GetTypeInfo().Assembly.FullName;
        typeName = serializedType.FullName;
#else
        assemblyName = serializedType.Assembly.FullName;
        typeName = serializedType.FullName;
#endif
}

Then, set the Binder property of your JsonSerializer to an instance of your custom SerializationBinder before calling Serialize or Deserialize.

Your implementation might look something like:

public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
     //http://stackoverflow.com/questions/2483023/how-to-test-if-a-type-is-anonymous
     if(Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
    && type.IsGenericType && type.Name.Contains("AnonymousType")
    && (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
    && (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic)
    {
        return "AnonymousType";
    }
    base.BindToName(serializedType, out assemblyName, out typeName);
}
Joe Enzminger
  • 11,110
  • 3
  • 50
  • 75
  • There is obvious error in this code: `BindToName` has no return type. Did you mean to set the `out` variables to some values? – Kędrzu Sep 30 '16 at 12:31
  • Remember to also set `base.BindToName(serializedType, out assemblyName, out typeName);` in `else` clause :) – Kędrzu Sep 30 '16 at 12:32