#c# #visual-studio-2010 #serialization #xmlserializer #deserialization
#c# #visual-studio-2010 #сериализация #xmlserializer #десериализация
Вопрос:
Почему Deserialize
возникает исключение после того, как я обновил Visual Studio 2010?
РЕДАКТИРОВАТЬ (изменение вопроса):
Я заставил его работать, удалив using
инструкцию и вызвав Dispose
вручную TextReader gTr
.
Новый вопрос:
Почему using
инструкция вызывает ошибки при чтении с помощью TextReader
(после обновления)?
Я сбит с толку этим. Все, что я сделал, это обновил Visual Studio, и это больше не работает. Раньше это работало отлично (в течение нескольких недель). Это также соответствует многим примерам, которые я прочитал. Я не вижу, как что-то из этого неправильно, или как Root
отсутствует, или как существует error in XML document (0, 0)
.
//EXCEPTION
System.InvalidOperationException was caught
Message=There is an error in XML document (0, 0).
Source=System.Xml
InnerException: System.Xml.XmlException
Message=Root element is missing.
LineNumber=0
LinePosition=0
//SERIALIZE
SGlobalSettings gSettings = new SGlobalSettings();
XmlSerializer gXmls = new XmlSerializer(typeof(SGlobalSettings));
using (TextWriter gTw = new StreamWriter("global.xml"))
{
gXmls.Serialize(gTw, gSettings);
}
//DESERIALIZE
if (File.Exists("global.xml"))
{
SGlobalSettings global;
XmlSerializer gXmls = new XmlSerializer(typeof (SGlobalSettings));
using (TextReader gTr = new StreamReader("global.xml"))
{
global = (SGlobalSettings)gXmls.Deserialize(gTr);
}
}
//OBJECT
[XmlRootAttribute("Global")]
public class SGlobalSettings
{
public string key { get; set; }
public string last { get; set; }
public SGlobalSettings() { }
}
//XML
<?xml version="1.0" encoding="utf-8" ?>
<Global xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<key>KEY</key>
<last>LAST</last>
</Global>
Спасибо за любую помощь!!!
Комментарии:
1. Кажется, десериализуется нормально для меня, используя ваш код как есть. Убедитесь, что у вас нет пробелов перед
<?xml version="1.0" encoding="utf-8" ?>
.2. Я только что выполнил приведенный выше код, сериализовав объект, а затем десериализовав, без исключения (VS2010). Может быть, это вызвано чем-то другим, что вы не включили?
3. @Bala: Я заставил это работать и отредактировал свой вопрос, чтобы отразить мои новые выводы. Что касается пробелов, я не создаю XML-файл, он на 100% сгенерирован с использованием приведенного выше кода
XmlSerializer
.
Ответ №1:
У меня была точно такая же проблема раньше. Мое лучшее предположение заключается в том, что «корневой элемент», который ищет XmlSerializer, — это элемент с тем же именем, что и тип, который он пытается десериализовать. Итак, изменение вашего XML на следующее должно сработать: (изменения выделены жирным шрифтом)
<?xml version="1.0" encoding="utf-8" ?>
<SGlobalSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<key>KEY</key>
<last>LAST</last>
</SGlobalSettings>
Я не знаю, почему TextReader будет неправильно считывать файл при автоматическом удалении, но знаете ли вы, что существует перегрузка, XmlSerializer.Deserialize
которая принимает Stream
экземпляр в качестве аргумента? Использование этой перегрузки может решить вашу проблему; может существовать несколько перегрузок, потому что каждая из них использует базовый поток по-разному. Похоже, это синхронизировано с типичными, загадочно скрытыми перехватами Microsoft.
Я бы попробовал полностью обойти TextReader и использовать вместо этого следующий код:
XmlSerializer gXmls = new XmlSerializer(typeof (SGlobalSettings));
using (Stream gStream = File.OpenRead("global.xml"))
{
global = (SGlobalSettings)gXmls.Deserialize(gStream);
}
Комментарии:
1. Проблема не в этом. Каким-то образом
TextReader
сusing
это портит.2. Извините, @PiZzL3… Моя ошибка. Я не видел атрибут XmlRootAttribute в вашем классе, и я ответил перед вашим редактированием, для загрузки. Я обновил свой ответ, чтобы отразить ваши изменения.
Ответ №2:
Ошибка в (0, 0) обычно означает, что ваш код может открыть файл, но файл пуст. Попробуйте использовать метод Flush () в разделе serialize.
Кроме того, ваш код отлично работает в моей Visual Studio 2010 с пакетом обновления 1;