【问题标题】:DataContractSerializer - Name cannot begin with the '.' character, hexadecimal value 0x2EDataContractSerializer - 名称不能以“.”开头字符,十六进制值 0x2E
【发布时间】:2016-09-14 06:51:37
【问题描述】:

这个问题在 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的一个sn-p是

<?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 年来一切正常,问题从今天开始。

非常感谢任何提示, 丹尼尔

更新

我添加了最少量的代码来重现问题hereapplication 尝试从 xml 文件中读取给定的类,具有问题 dataContractNames 的类位于 library\+support\+qprimitive

【问题讨论】:

  • 您的 XML 无效。 第 2 行的 XML 解析错误:xmlns: URI libTypes.salesApp 不是绝对的 验证给定示例后
  • _x002E_XmlConvert.EncodeLocalName() 对字符串"." 进行编码的方式。所以你的&lt;d2p1:_x002E_&gt;&lt;d4p1:_x002E_&gt; 元素都有本地名称,在解码时映射到"."。见dotnetfiddle.net/phUYO3。您能否分享与DateOfValidity 对应的类型,以便我们查看 XML 是如何生成的?是实现IXmlSerializable还是ISerializable
  • 更好的是,你能分享一个minimal reproducible example 来序列化产生&lt;d2p1:_x002E_&gt; 元素的类型吗?
  • @dbc:谢谢,就是这样。我的一个课程使用[DataMember(Name = ".")] - 我在写这篇文章时是 XML 新手,我想“让我们让 XML 更小”。有趣的是,运行时多年来都没有抱怨过这个问题。现在......有很多使用这种格式编写的文件,我可以对代码进行的最小更改是什么,使我可以读取这些文件?使用此 DataMemberName 的类只有一个成员并且是密封的。我尝试使用 [DataMember(Order = 0)] 而不是 DataMemberName,但没有帮助。非常感谢!
  • @DanielBencik - 我尝试用[DataMember(Name = ".")] 制作一个示例类,并且能够成功反序列化它。为了帮助更多,能否分享一下上面反序列化XML失败的类?或者您能否通过源代码控制确定过去几天发生的变化?如果没有minimal reproducible example,我会花时间猜测你的类定义是什么,并尝试看看我是否可以重现这个问题,这不太可能很快成功。

标签: c# xml datacontractserializer


【解决方案1】:

_x002E_XmlConvert.EncodeLocalName() 编码字符串"." 的方式。请参阅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; }
}

【讨论】:

  • 首先,非常感谢。继承问题是我在创建示例项目期间的错 - 有一个大约列表。基类之后的八个接口,在从派生类声明中删除接口的过程中,我也删除了基类。我更新了链接的解决方案。但是,其次,当我同时运行旧解决方案和此更新解决方案时,我仍然会遇到带有“。”的异常。而且我理解你为什么没有得到它......我昨天晚上没有收到那个异常 - 没有明显的原因。
  • @DanielBencik - 你的问题不再重现了吗?
  • 看来是这样。但是,考虑到当运行时抱怨时,它会抱怨“.”。我很乐意将您的帖子作为答案。
猜你喜欢
  • 2021-06-26
  • 2019-10-25
  • 2017-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 1970-01-01
  • 2018-08-09
相关资源
最近更新 更多