DataContractSerializer — имя не может начинаться с «.». символ, шестнадцатеричное значение 0x2E

Этот вопрос задавался много раз на SO, но ни одно решение не помогло мне.

Моя структура данных сериализуется в файл XML с помощью dataContractSerializer. Код (де)сериализации следующий:

    public static void serialize<T>(T xObject, string xFilePath, string xIndent = "")
    {
        XmlWriterSettings xSettings = ( xIndent == "" ? new XmlWriterSettings  {Indent = false } : new XmlWriterSettings { Indent = true, IndentChars = xIndent } );

        using (XmlWriter xStream = XmlWriter.Create(xFilePath, xSettings))
            new DataContractSerializer(typeof(T)).WriteObject(xStream, xObject);
    }

    public static T deserialize<T>(string xFilePath)
    {
        using (FileStream xStream = new FileStream(xFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            DataContractSerializer xSerializer = new DataContractSerializer(typeof(T));
            return (T)xSerializer.ReadObject(xStream);
        }
    }

Фрагмент написанного XML

<?xml version="1.0" encoding="utf-8"?>
<PxePriceListEod xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="libTypes.salesApp">
   <DateOfValidity xmlns:d2p1="libTypes">
       <d2p1:_x002E_>2016-09-09T00:00:00</d2p1:_x002E_>
   </DateOfValidity>
   <PriceRecords>
       <AbstractPxePriceRecordEod i:type="PxePriceRecordEodBal">
           <Product xmlns:d4p1="libTypes">
               <d4p1:Ccy>
                   <d4p1:_x002E_>EUR</d4p1:_x002E_>
               </d4p1:Ccy>
               <d4p1:Commodity>
                   <d4p1:_x002E_>Electricity</d4p1:_x002E_>
               </d4p1:Commodity>
               <d4p1:Duration>
                   <d4p1:_x002E_>Month</d4p1:_x002E_>
               </d4p1:Duration>
               <d4p1:Exchange>
                   <d4p1:_x002E_>Pxe</d4p1:_x002E_>
               </d4p1:Exchange>
               <d4p1:Period>
                   <d4p1:_x002E_>9</d4p1:_x002E_>
               </d4p1:Period>
               <d4p1:Type>
                   <d4p1:_x002E_>Base</d4p1:_x002E_>
               </d4p1:Type>
               <d4p1:Year>
                   <d4p1:_x002E_>2016</d4p1:_x002E_>
               </d4p1:Year>
           </Product>
           <IsDeduced xmlns:d4p1="libTypes">
               <d4p1:_x002E_>false</d4p1:_x002E_>
           </IsDeduced>
           <IsInterpolated xmlns:d4p1="libTypes">
                  <d4p1:_x002E_>false</d4p1:_x002E_>
           </IsInterpolated>
           <IsSynthetic xmlns:d4p1="libTypes">
               <d4p1:_x002E_>false</d4p1:_x002E_>
           </IsSynthetic>
           <Price xmlns:d4p1="libTypes">
               <d4p1:_x002E_>30.45</d4p1:_x002E_>
           </Price>
           <DateOfValidity xmlns:d4p1="libTypes">
               <d4p1:_x002E_>2016-09-09T00:00:00</d4p1:_x002E_>
           </DateOfValidity>
       </AbstractPxePriceRecordEod>
       ... more AbstractPxePriceRecordEod elements ...
     </PriceRecords>
  </PxePriceListEod>

Особенности проблемы:

  1. Ошибка указывает на Line=0, Position=1 (что не имеет смысла)
  2. Нет элемента с именем, содержащим "."
  3. Все классы, которые попадают в файл, должным образом украшены DataContract
  4. XML-файл проверяется на действительность в кодировке UTF-8 (при чтении Notepad++), и ни одна из других версий (де) сериализующего кода, перечисленных в SO (которые неявно указывают кодировку UTF-8), не помогла
  5. Я знаю, что файл уродлив (автоматически сгенерированные имена элементов, такие как "d4p1:x002E" - я единственный разработчик в этой компании, и, к сожалению, у меня нет времени, чтобы красиво оформить более 100 классов)
  6. Все работало нормально 2,5 года, сегодня начались проблемы.

Любой намек очень ценится, Даниэль

ОБНОВЛЕНИЕ

Я добавил минимальное количество кода, который воспроизводит проблему здесь . application пытается прочитать данный класс из файла xml, классы с проблемными dataContractNames находятся в library\+support\+qprimitive.


person Daniel Bencik    schedule 14.09.2016    source источник
comment
Ваш XML недействителен. Ошибка синтаксического анализа XML в строке 2: xmlns: URI libTypes.salesApp не является абсолютным после проверки данного примера   -  person lokusking    schedule 14.09.2016
comment
_x002E_ это то, как XmlConvert.EncodeLocalName()< /a> кодирует строку ".". Таким образом, все ваши элементы <d2p1:_x002E_> и <d4p1:_x002E_> имеют локальные имена, которые при декодировании сопоставляются с ".". См. dotnetfiddle.net/phUYO3. Можете ли вы поделиться типом, соответствующим DateOfValidity, чтобы мы могли увидеть, как был сгенерирован XML? Он реализует IXmlSerializable или ISerializable?   -  person dbc    schedule 14.09.2016
comment
А еще лучше, можете ли вы поделиться минимально воспроизводимым примером, который сериализует типы, которые производят эти <d2p1:_x002E_> элементы?   -  person dbc    schedule 14.09.2016
comment
@dbc: Спасибо, это все. Один из моих классов использует [DataMember(Name = ".")] — я был новичком в XML, когда писал это, и решил, что давайте сделаем XML меньше. Самое смешное, что среда выполнения не жаловалась на это годами. Теперь... имея много файлов, написанных с использованием этого формата, какое наименьшее изменение я могу внести в код, который позволит мне читать эти файлы? Класс, который использует это DataMemberName, имеет только один член и является запечатанным. Я пробовал использовать [DataMember(Order = 0)] вместо DataMemberName, но не помогло. Большое спасибо!   -  person Daniel Bencik    schedule 14.09.2016
comment
@DanielBencik - я попытался создать образец класса с [DataMember(Name = ".")] и смог успешно его десериализовать. Чтобы помочь больше, можете ли вы поделиться классами, которые не могут десериализовать приведенный выше XML? Или вы можете определить, что изменилось за последние несколько дней, с помощью системы контроля версий? Без минимального воспроизводимого примера я буду тратить свое время на то, чтобы угадать, каковы ваши определения классов, и экспериментировать, чтобы увидеть, смогу ли я может воспроизвести проблему, что вряд ли удастся быстро.   -  person dbc    schedule 14.09.2016
comment
@dbc: A внес изменения, связанное решение показывает проблему. Самое смешное, что это решение дает ошибки на всех файлах, даже на тех, на которых все решение работало нормально.   -  person Daniel Bencik    schedule 14.09.2016
comment
@dbc: в любом случае, я исправлю это вручную. Не могли бы вы сделать ответ из вашего комментария, чтобы я мог его принять?   -  person Daniel Bencik    schedule 15.09.2016


Ответы (1)


_x002E_ как XmlConvert.EncodeLocalName() кодирует строку ".". См. https://dotnetfiddle.net/phUYO3 для демонстрации. Итак, вы либо:

  • Иметь член данных с "." в качестве имени.
  • Реализовали IXmlSerializable и пишем элементы с этим именем.

При этом создание типа контракта данных с [DataMember(Name = ".")] для одного из членов данных не вызывает у меня проблем. т.е. Я могу успешно сериализовать и десериализовать следующее:

[DataContract(Namespace = "libTypes.salesApp")]
public class PxePriceListEod
{
    [DataMember]
    public DateOfValidity DateOfValidity { get; set; }
}

// DateOfValidity 
[DataContract(Namespace = "libTypes")]
public class DateOfValidity
{
    [DataMember(Name = ".")]
    public DateTime DateTime { get; set; }
}
person dbc    schedule 15.09.2016
comment
Во-первых, большое спасибо. Проблема с наследованием - моя вина при создании примера проекта - там был список ок. восемь интерфейсов, следующих за базовым классом, и во время удаления интерфейсов из объявления производного класса я также удалил базовый класс. Я обновил связанное решение. Во-вторых, однако, когда я запускаю и старое, и это обновленное решение, я все равно получаю исключение с .. И я понимаю, почему вы его не получаете ... Вчера ночью я перестал получать это исключение - без видимой причины. - person Daniel Bencik; 15.09.2016
comment
@DanielBencik - так ваша проблема больше не воспроизводится? - person dbc; 15.09.2016
comment
Кажется так. Но, принимая во внимание, что когда среда выполнения жалуется, она жалуется на . Я с большим удовольствием приму ваш пост в качестве ответа. - person Daniel Bencik; 20.09.2016