DataContractSerializer - 名称不能以“.”开头字符,十六进制值 0x2E
DataContractSerializer - Name cannot begin with the '.' character, hexadecimal value 0x2E
这个问题已经在 SO 上被问了很多次,但没有一个解决方案对我有帮助。
我的数据结构使用 dataContractSerializer 序列化为 XML 文件。 (反)序列化代码如下:
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(没有意义)
- 没有名称中包含“.”的元素
- 所有进入文件的 classes 都被正确修饰
DataContract
- XML 文件被检查为确实是 UTF-8 编码(当被 Notepad++ 读取时)和 none 上列出的其他版本的(反)序列化代码(隐含地指定 UTF-8 编码)帮助
- 我知道文件很丑(自动生成的元素名称如 "d4p1:x002E" - 我是这家公司唯一的开发人员,不幸的是我没有时间很好地装饰 100+ classes)
- 2.5 年来一切正常,今天开始出现问题。
非常感谢任何提示,
丹尼尔
更新
我添加了最少量的代码来重现问题 here。 application
尝试从 xml 文件中读取给定的 class,具有有问题数据合同名称的 classes 位于 library\+support\+qprimitive
中。
_x002E_
是如何XmlConvert.EncodeLocalName()
encodes the string "."
. See https://dotnetfiddle.net/phUYO3进行演示的。所以你要么:
- 有一个以
"."
作为名称的数据成员。
- 已实施
IXmlSerializable
并正在使用此名称编写元素。
也就是说,在其中一个数据成员上使用 [DataMember(Name = ".")]
制定数据协定类型对我来说不会造成问题。 IE。我可以成功序列化和反序列化以下内容:
[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; }
}
这个问题已经在 SO 上被问了很多次,但没有一个解决方案对我有帮助。
我的数据结构使用 dataContractSerializer 序列化为 XML 文件。 (反)序列化代码如下:
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(没有意义)
- 没有名称中包含“.”的元素
- 所有进入文件的 classes 都被正确修饰
DataContract
- XML 文件被检查为确实是 UTF-8 编码(当被 Notepad++ 读取时)和 none 上列出的其他版本的(反)序列化代码(隐含地指定 UTF-8 编码)帮助
- 我知道文件很丑(自动生成的元素名称如 "d4p1:x002E" - 我是这家公司唯一的开发人员,不幸的是我没有时间很好地装饰 100+ classes)
- 2.5 年来一切正常,今天开始出现问题。
非常感谢任何提示, 丹尼尔
更新
我添加了最少量的代码来重现问题 here。 application
尝试从 xml 文件中读取给定的 class,具有有问题数据合同名称的 classes 位于 library\+support\+qprimitive
中。
_x002E_
是如何XmlConvert.EncodeLocalName()
encodes the string "."
. See https://dotnetfiddle.net/phUYO3进行演示的。所以你要么:
- 有一个以
"."
作为名称的数据成员。 - 已实施
IXmlSerializable
并正在使用此名称编写元素。
也就是说,在其中一个数据成员上使用 [DataMember(Name = ".")]
制定数据协定类型对我来说不会造成问题。 IE。我可以成功序列化和反序列化以下内容:
[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; }
}