Этот вопрос задавался много раз на 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>
Особенности проблемы:
- Ошибка указывает на Line=0, Position=1 (что не имеет смысла)
- Нет элемента с именем, содержащим "."
- Все классы, которые попадают в файл, должным образом украшены
DataContract
- XML-файл проверяется на действительность в кодировке UTF-8 (при чтении Notepad++), и ни одна из других версий (де) сериализующего кода, перечисленных в SO (которые неявно указывают кодировку UTF-8), не помогла
- Я знаю, что файл уродлив (автоматически сгенерированные имена элементов, такие как "d4p1:x002E" - я единственный разработчик в этой компании, и, к сожалению, у меня нет времени, чтобы красиво оформить более 100 классов)
- Все работало нормально 2,5 года, сегодня начались проблемы.
Любой намек очень ценится, Даниэль
ОБНОВЛЕНИЕ
Я добавил минимальное количество кода, который воспроизводит проблему здесь . application
пытается прочитать данный класс из файла xml, классы с проблемными dataContractNames находятся в library\+support\+qprimitive
.
_x002E_
это то, какXmlConvert.EncodeLocalName()
< /a> кодирует строку"."
. Таким образом, все ваши элементы<d2p1:_x002E_>
и<d4p1:_x002E_>
имеют локальные имена, которые при декодировании сопоставляются с"."
. См. dotnetfiddle.net/phUYO3. Можете ли вы поделиться типом, соответствующимDateOfValidity
, чтобы мы могли увидеть, как был сгенерирован XML? Он реализуетIXmlSerializable
илиISerializable
? - person dbc   schedule 14.09.2016<d2p1:_x002E_>
элементы? - person dbc   schedule 14.09.2016[DataMember(Name = ".")]
— я был новичком в XML, когда писал это, и решил, что давайте сделаем XML меньше. Самое смешное, что среда выполнения не жаловалась на это годами. Теперь... имея много файлов, написанных с использованием этого формата, какое наименьшее изменение я могу внести в код, который позволит мне читать эти файлы? Класс, который использует это DataMemberName, имеет только один член и является запечатанным. Я пробовал использовать [DataMember(Order = 0)] вместо DataMemberName, но не помогло. Большое спасибо! - person Daniel Bencik   schedule 14.09.2016[DataMember(Name = ".")]
и смог успешно его десериализовать. Чтобы помочь больше, можете ли вы поделиться классами, которые не могут десериализовать приведенный выше XML? Или вы можете определить, что изменилось за последние несколько дней, с помощью системы контроля версий? Без минимального воспроизводимого примера я буду тратить свое время на то, чтобы угадать, каковы ваши определения классов, и экспериментировать, чтобы увидеть, смогу ли я может воспроизвести проблему, что вряд ли удастся быстро. - person dbc   schedule 14.09.2016