XMLSerializer - проблема с UTF-8 против кода UTF-16 - PullRequest
0 голосов
/ 28 августа 2018

Я пытаюсь сериализовать простой объект (5 строковых свойств) в XML, чтобы сохранить его в поле изображения БД. Затем мне нужно десериализовать его обратно в строку позже в программе.
Тем не менее, я получаю некоторые ошибки - вызванные сохранением XML, думая, что он находится в UTF-16 - однако, когда я загружаю его из БД обратно в строку - он думает, что это строка UTF 8.

Я получаю ошибку

  • InnerException {"Отсутствует метка порядка байтов в Юникоде. Невозможно переключиться в Юникод."} System.Exception {System.Xml.XmlException} - Сообщение «Ошибка в XML-документе (0, 0).» строка

Это происходит из-за двух разных способов сохранения и загрузки строки в / из БД? При сохранении я использую StringBuilder, но при загрузке из БД я использую только строку.

Мысли?

Сериализация и сохранение в БД

        // Now Save the OBject XML to the Query Tables
        var serializer = new XmlSerializer(ExportConfig.GetType());
        StringBuilder StringResult = new StringBuilder();
        using (var writer = XmlWriter.Create(StringResult))
        {
           serializer.Serialize(writer, ExportConfig);
        }
        //MessageBox.Show("XML :  " + StringResult);
        // Now Save to the Query

    try
    {
        string UpdateSQL = "Update ZQryRpt "
                     + "  Set ExportConfig = " + TAGlobal.QuotedStr(StringResult.ToString())
                     + "  where QryId = " + TAGlobal.QuotedStr(((DataRowView)bindingSource_zQryRpt.Current).Row["QryID"].ToString())
                     ;
        ExecNonSelectSQL(UpdateSQL, uniConnection_Config);
    }
    catch (Exception Error)
    {
        MessageBox.Show("Error Setting ExportConfig: " + Error.Message);
    }

Загрузка из БД и десериализация

    byte[] binaryData = (byte[])((DataRowView)bindingSource_zQryRpt.Current).Row["ExportConfig"];
    string XMLStored = System.Text.Encoding.UTF8.GetString(binaryData, 0, binaryData.Length);

    if (XMLStored.Length > 0)
    {
        IIDExportObject ExportConfig = new IIDExportObject();
        var serializer = new XmlSerializer(ExportConfig.GetType());
        //StringBuilder StringResult = new StringBuilder(XMLStored);
        // Load the XML from the Query into the StringBuilder

        // Now we need to build a Stream from the String to use in the XMLReader
        byte[] byteArray = Encoding.UTF8.GetBytes(XMLStored);
        MemoryStream stream = new MemoryStream(byteArray);
        using (var reader = XmlReader.Create(stream))
        {
            ExportConfig = (IIDExportObject)serializer.Deserialize(reader);
        }
    }

1 Ответ

0 голосов
/ 29 августа 2018

Джон - большое спасибо за комментарий! Это позволило мне завершить код и найти решение.

Как вы заметили - использование потокового считывателя было решением - но я не мог прочитать первую строку, потому что в моей строке была только одна «строка». Тем не менее, я мог бы использовать строку

            using (StreamReader sr = new StreamReader(stream, false))

Что позволяет мне читать поток и игнорировать "Обнаружение метки порядка байтов", установленное в false.

    string XMLStored = MainFormRef.GetExportConfigForCurrentQuery();
    if (XMLStored.Length > 0)
    {
        IIDExportObject ExportConfig = new IIDExportObject();
        try
        {
            var serializer = new XmlSerializer(ExportConfig.GetType());
            // Now we need to build a Stream from the String to use in the XMLReader
            byte[] byteArray = Encoding.UTF8.GetBytes(XMLStored);
            MemoryStream stream = new MemoryStream(byteArray);
            // Now we need to use a StreamReader to get around UTF8 vs UTF16 issues
            //   A little cumbersome - but it works
            using (StreamReader sr = new StreamReader(stream, false))
            {
                using (var reader = XmlReader.Create(sr))
                {
                    ExportConfig = (IIDExportObject)serializer.Deserialize(reader);
                }
            }
        }
        catch
        {

        }

Я не уверен, что это лучшее решение - но оно работает. Мне было бы любопытно узнать, есть ли у кого-то еще лучший способ справиться с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...