Обработка изменений пространства имен с помощью TypeNameHandling.All

Мне удалось завести себя в исправление с помощью JSON.net TypeNameHandling. Я сохраняю JSON-форматированный объект с использованием RavenDB и устанавливаю для параметра TypeNameHandling сериализатора JSON.net значение true, чтобы иметь дело с структурой наследования, которую я имею.

Мне нужно было изменить пространство имен документа, который я храню, поэтому теперь, когда он десериализуется, он выдает ошибку "Тип разрешения ошибки, указанный в JSON", потому что ссылка на тип в документе JSON больше не существует.

Можно ли перехватить десериализацию Json, чтобы выполнить какую-то скользящую миграцию?

Спасибо,

Ответ 1

Хорошо, понял. В конце концов, это было довольно прямолинейно. Вам необходимо переопределить DefaultSerializationBinder, который отвечает за создание типа .Net из документа. Поскольку у моего json-документа есть старое пространство имён, мне нужно перехватить создание этого типа, чтобы вернуть правильный тип. Я собрал простую реализацию, которая позволит вам настроить "миграции" при создании сериализатора JSON.

    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);
        }
    }

Если интерфейс

public interface INamespaceMigration
{
    string FromAssembly { get; }

    string FromType { get; }

    Type ToType { get; }
}