Сериализация объекта в строку: почему моя кодировка добавляет глупые символы? - PullRequest
4 голосов
/ 03 августа 2011

Мне нужно получить сериализованное 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;
  }
}

Теперь просто обратите внимание на строки xml.substring на мгновение.Я обнаружил, что (даже подумал, что я задаю кодировку для XmlTextWriter и GetString (и я использую memoryStream.ToArray (), поэтому я работаю только с данными в буфере потока) ... В результирующей строке xml добавлен не-xml счастливый символ. В моем случае, «?» в начале строки. Вот почему я подставляю «<» и «>», чтобы убедиться, что «я»Мы только получаем хорошие вещи.

Странно, глядя на эту строку в отладчике (Text Visualizer), я не вижу этого «?». Только когда я вставляю то, что находится в визуализаторе, в блокнот илипохоже.

Итак, хотя вышеприведенный код (подстрока и т. д.) выполняет свою работу, что на самом деле здесь происходит? Включена ли какая-то вещь без знака в байт и не представлена ​​в визуализаторе текста?

Ответы [ 2 ]

8 голосов
/ 03 августа 2011

Вы можете исключить спецификацию, указав кодировку - т.е. вместо 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);
}
6 голосов
/ 03 августа 2011

На что вы смотрите: Метка порядка байтов (BOM) . Это нормально в UTF8!

Короче говоря, для фанатов моего комментария: это байтовые маркеры, которые определяют порядковый номер строки.

Что вы можете сделать, это либо использовать a) ASCII в качестве вашей кодировки, которая будет сбрасывать метки порядка байтов ... или b) почему бы не оставить их? В конце концов, они служат полезной функцией для вашей строки xml.

Марк Гравелл (Marc Gravell) ниже дает третью альтернативу , создав собственный объект кодирования и указав false в конструкторе для подавления маркеров порядка байтов.

...