Десериализовать объект .NET неизвестного типа с помощью BinaryFormatter - PullRequest
0 голосов
/ 11 мая 2018

Я пытаюсь десериализовать некоторые объекты, используя BinaryFormatter, где сериализованные объекты могут содержать неизвестные типы, типы, которые были сериализованы из сборок, которых нет в приложении десериализации.В случае, если тип неизвестен, я хотел бы просто десериализовать его как нулевое значение.

Я натолкнулся на этот поток в социальной сети Microsoft , который не нашел решения.,Поток ссылается на этот вопрос , который также не имеет ответа, но касается XML, а не двоичного форматирования.

1 Ответ

0 голосов
/ 16 мая 2018

Этот вопрос, возможно, мог бы быть написан более подробно, но я не знал, с чего начать. С тех пор я разобрался с решением, так что вот подробности.

Во-первых, вы должны реализовать SerializationBinder . В переопределении BindToType вам дается имя сборки и имя типа в виде строк. Если имя сборки относится к сборке, о которой вы не знаете, верните тип маркера, который указывает, что он неизвестен; Я создал class UnknownType {} для этой цели.

class UnknownType { }

class UnknownBinder : SerializationBinder
{
    bool IsUnknown(string asmName)
    {
        // your impl here
        throw new NotImplementedException();
    }

    public override Type BindToType(string assemblyName, string typeName)
    {
        if(IsUnknown(assemblyName))
        {
            return typeof(UnknownType);
        }
        return Type.GetType(typeName);
    }
}

Вторым шагом является реализация ISurrogateSelector и ISerializationSurrogate . Они будут реализованы так, чтобы «возвращать ноль» каждый раз, когда встречается UnknownType.

class UnknownSurrogateSelector : ISurrogateSelector, ISerializationSurrogate
    {
        public void ChainSelector(ISurrogateSelector selector)
        {
        }

        public ISurrogateSelector GetNextSelector()
        {
            return null;
        }

        public ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector)
        {
            if(type == typeof(UnknownType))
            {
                selector = this;
                return this;
            }
            selector = null;
            return null;
        }

        public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
        {
            throw new NotImplementedException();
        }

        public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
        {
            if (obj is UnknownType)
                return null;
            return obj;
        }
    }

Суррогатный селектор присоединен к элементу SurrogateSelector экземпляра BinaryFormatter, а связыватель присоединен к члену Binder.

...