将对象序列化为字符串:为什么我的编码添加了愚蠢的字符?

MoS*_*Slo 4 c# encoding xml-serialization

我需要将对象的序列化XML表示形式作为字符串.我正在使用XmlSerializer和memoryStream来执行此操作.

XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
using (MemoryStream stream = new MemoryStream())
{
  using (XmlTextWriter writer = new XmlTextWriter(stream,Encoding.UTF8))
  {
    serializer.Serialize(writer, myClass);
    string xml = Encoding.UTF8.GetString(stream.ToArray());
    //other chars may be added from the encoding.
    xml = xml.Substring(xml.IndexOf(Convert.ToChar(60)));
    xml = xml.Substring(0, (xml.LastIndexOf(Convert.ToChar(62)) + 1));
    return xml;
  }
}
Run Code Online (Sandbox Code Playgroud)

现在只需记下xml.substring行.我发现的是(甚至认为我在XmlTextWriter和GetString上指定编码(我正在使用memoryStream.ToArray(),所以我只对流的缓冲区中的数据进行操作).产生的xml字符串添加了一些非xml快乐字符.在我的例子中,字符串开头是'?'.这就是为什么我要为'<'和'>'子字符串来确保我''只有得到好东西.

奇怪的是,在调试器中看到这个字符串(Text Visualizer),我没有看到这个'?'.只有当我将可视化器中的内容粘贴到记事本或类似内容中时.

因此,虽然上面的代码(substring etc)可以完成这项工作,但实际上这里发生了什么?是否包含一些无符号字节的东西,而不是在Text Visualizer中表示?

Mar*_*ell 8

您可以通过专门指定编码来排除BOM - 即代替Encoding.UTF8,尝试使用:

using (MemoryStream stream = new MemoryStream())
{
  var enc = new UTF8Encoding(false);
  using (XmlTextWriter writer = new XmlTextWriter(stream,enc))
  {
    serializer.Serialize(writer, myClass);        
  }
  string xml = Encoding.UTF8.GetString(
      stream.GetBuffer(), 0, (int)stream.Length);
}
Run Code Online (Sandbox Code Playgroud)


Jaa*_*jan 6

您正在查看的是字节顺序标记(BOM).这是正常的UTF8!

简而言之,对于我的评论粉丝:它们是字节标记,用于确定字符串的字节顺序.

您可以做的是使用a)ASCII作为编码,这将删除字节顺序标记..或b)为什么不留下它们?它们确实为xml字符串提供了有用的功能.

下面的Marc Gravell 通过创建自己的编码对象并在构造函数中指定false以抑制字节顺序标记来提供第三种方法.