Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling namespace changes with TypeNameHandling.All

I managed to get my self into a fix with the JSON.net TypeNameHandling. I am storing a JSON formatted object using RavenDB and set the TypeNameHandling of the JSON.net serializer to true in order to deal with an inheritance structure I have in place.

I needed to change the namespace of the document which I am storing, so now when it is deserialzed it is throws the error "Error resolving type specified in JSON" because the reference to the type in the JSON document no longer exists.

Is it possible to intercept the Json deserialization in order to do some kind of rolling migration?

Thanks,

like image 697
Ross Jones Avatar asked Mar 28 '12 13:03

Ross Jones


1 Answers

Ok, figured it out. In the end it was pretty straight forward. You need to override the DefaultSerializationBinder which is responsible for creating the .Net type from the document. Since my json document has the old namespace in it, I needed to intercept the creation of that type to return the correct type. I put together a simple implementation which will allow you to configure "migrations" when the JSON serializer is created.

    public class NamespaceMigrationSerializationBinder : DefaultSerializationBinder
    {
        private readonly INamespaceMigration[] _migrations;

        public NamespaceMigrationSerializationBinder(params INamespaceMigration[] migrations)
        {
            _migrations = migrations;
        }

        public override Type BindToType(string assemblyName, string typeName)
        {
            var migration = _migrations.SingleOrDefault(p => p.FromAssembly == assemblyName && p.FromType == typeName);
            if(migration != null)
            {
                return migration.ToType;
            }
            return base.BindToType(assemblyName, typeName);
        }
    }

Where the interface is

public interface INamespaceMigration
{
    string FromAssembly { get; }

    string FromType { get; }

    Type ToType { get; }
}
like image 169
Ross Jones Avatar answered Nov 14 '22 09:11

Ross Jones