C #, почему использование TextReader вызывает исключение после обновления Visual Studio?

#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;