Serializing Type objects

Jan 28, 2010 at 9:24 PM

I was trying to serialize a list of types but when reloading it cant reload the type since it only serialized the type name and not the assembly qualifed name .

for example:

Class myClass

{

    public IList<Type> m_myTypes;

}

myClass myClass= new myClass();

myClass.m_myTypes.Add(typeof(myCLass));

this will serialize ok but the class type information serliazed will only be the class name itself and when it deserializes it , it will fail since it doesnt know what assembly its in.

This seems quite common so I assume there is something to handle this but I cant figure that out. Is there some custom conversion class needed to do this?

I think it should really do this automatically for all types but if there is something I can put it to override this default behavior would be fine too.

 

thanks

 

scott

Jan 29, 2010 at 1:52 PM

I was able to get it working by implementing a TypeConverter for Types but Im wondering if this type of converter should be baked in by default since storing a type without an assembly name wouldnt be of any use. This is the type converter I used that seemed to work:

 

     /// <summary>
      /// Converts a Type value to and from a string value.
      /// </summary>
      public class TypeConverter : JsonConverter
      {
         /// <summary>
         /// Writes the JSON representation of the object.
         /// </summary>
         /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
         /// <param name="value">The value.</param>
         /// <param name="serializer">The calling serializer.</param>
         public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
         {
            if (value == null)
            {
               writer.WriteNull();
               return;
            }
      
            writer.WriteValue(((Type)value).FullName +", "+((Type)value).Assembly.GetName().Name);
         }
    
         /// <summary>
         /// Reads the JSON representation of the Type object.
         /// </summary>
         /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
         /// <param name="objectType">Type of the object.</param>
         /// <param name="serializer">The calling serializer.</param>
         /// <returns>The object value.</returns>
         public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
         {
            if (reader.TokenType == JsonToken.Null)
               return null;

            string encodedData = reader.Value.ToString();
            if (encodedData.Length > 0)
               return  Type.GetType(encodedData);

            return null;
         }

         /// <summary>
         /// Determines whether this instance can convert the specified object type.
         /// </summary>
         /// <param name="objectType">Type of the object.</param>
         /// <returns>
         ///  <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
         /// </returns>
         public override bool CanConvert(Type objectType)
         {
            if (objectType.IsAssignableFrom(typeof(Type).GetType()))
               return true;
           
            return false;
         }
      }

Coordinator
Jan 31, 2010 at 4:35 AM

Good point. I had a test to convert a type located in the mscorlib assembly back from a string but not a type out of a custom assembly. I've changed Json.NET so that it now writes type with the assembly qualified name.

Jan 31, 2010 at 4:46 PM

 thats great, its always possible to add a config to handle it but Im following the new idea of convention over configuration so the more it can automatically figure out the better.

thanks

 

scott