protobuf-net build v2.0.0.580 не может сериализовать System.Xml.Linq.XElement

Я просто заменил предыдущую сборку protobuf-net, которую использовал в своей кодовой базе (версия 2.0.0.480), на последнюю сборку (версия 2.0.0.580), поскольку в последняя версия protobuf, я ссылаюсь на полную DLL net30 в своих проектах.

При попытке сериализовать сложный тип, который включает System.Xml.Linq.XElement, я получаю InvalidOperationException от сериализатора protobuf - в сообщении об исключении говорится: «Сериализатор не определен для типа: System.Xml.Linq.XElement»

Я предполагаю, что отсутствие сериализатора для XElement связано с отсутствием сборки .Net 4.0 (поскольку в моем проекте я ссылаюсь на v4.0.30319 System.Xml.Linq.dll).

Мой проект нацелен на платформу .NET 4.5 — он отлично работает при ссылке на сборку protobuf-net V2.0.0.480 net40.


person dkfromthebay    schedule 28.09.2012    source источник
comment
Это не имеет ничего общего с 4.0; причина, по которой у меня нет сборки, специфичной для 4.0, заключается в том, что она не использует никаких типов/методов, специфичных для 4.0   -  person Marc Gravell    schedule 28.09.2012


Ответы (1)


Это выглядит так, как будто это связано с "анализируемыми типами" - вещами, которые не имеют встроенной обработки, но соответствуют определенным шаблонам, позволяющим рассматривать их как string. Это вызывало несколько проблем в прошлом, поэтому опционально поддерживается через .AllowParseableTypes:

static void Main()
{
    XElement el = XElement.Parse("<xml />");
    var model = TypeModel.Create(); // store and re-use this; don't use
    model.AllowParseableTypes = true; // a new one each time! (very bad)

    var foo = new Foo { Bar = el };
    var clone = (Foo) model.DeepClone(foo);
    var cloneEl = clone.Bar;
}
[ProtoContract]
class Foo
{
    [ProtoMember(1)]
    public XElement Bar { get; set; }
}

Обратите внимание, что причина, по которой мне пришлось объявить Foo здесь, заключается в том, что похоже, что обработка «корневого объекта» (которая сильно отличается от обработки элементов/подобъектов) не проверяет анализируемые типы; Я должен выяснить, почему нет, и исправить это. Я надеюсь, что следующее будет работать (в настоящее время это не работает, но, вероятно, должно):

static void Main()
{
    XElement el = XElement.Parse("<xml />");
    var model = TypeModel.Create(); // store and re-use this; don't use
    model.AllowParseableTypes = true; // a new one each time! (very bad)

    var cloneEl = (XElement)model.DeepClone(el);
}
person Marc Gravell    schedule 28.09.2012
comment
Привет, Марк, большое спасибо за быстрый ответ. Я решил просто изменить свою бизнес-логику: вместо передачи Xelement через мою службу WCF я сериализую XElement как строку перед использованием механизма сериализации protobuf-net на стороне сервера. Я проанализирую строку обратно в представление XElement. Я соответственно изменил атрибуты контракта protobuf, это было очень быстрое решение. Я должен был подумать об этом раньше, вместо того, чтобы тратить ваше драгоценное время. - person dkfromthebay; 28.09.2012
comment
Марк, есть ли дальнейший прогресс/другие обходные пути для этого сейчас? Я пытаюсь преобразовать устаревшую кодовую базу для использования Protobuf-net, и в самом конце (конечно) я наткнулся на элемент XElement, который возвращает то же исключение, что и OP для версии 2.0.0.622. - person Shaun; 27.11.2013
comment
@Shaun, помогает ли вышеизложенное? - person Marc Gravell; 27.11.2013
comment
@Marc - Это, безусловно, останавливает создание исключения, но проблемы, вызванные в прошлом, и (очень плохие) комментарии несколько помешали мне просто принять этот подход, особенно потому, что он применяется ко всей модели, а не только к этому конкретному члену, вот почему Я спросил, есть ли какие-либо другие обходные пути. Но, конечно, я поверю вам на слово, что это путь, пока опыт не докажет обратное :) - person Shaun; 27.11.2013
comment
Ааа, теперь я вижу, что очень плохой комментарий был о регенерации модели, извините за это. - person Shaun; 27.11.2013
comment
@Shaun проблемы возникают только тогда, когда они применяются без сознательного намерения к типам, где это не совсем уместно; самое плохое, как вы заметили, касается создания каждый раз новой модели - person Marc Gravell; 27.11.2013