Изменения XmlSerializer в .NET 3.5 SP1 - PullRequest
5 голосов
/ 29 августа 2008

Я видел довольно много сообщений об изменениях в .NET 3.5 с пакетом обновления 1 (SP1), но наткнулся на то, что я еще не видел документацию вчера. У меня был код, отлично работающий на моей машине, от VS, командной строки msbuild, всего, но на сервере сборки он не работал (работает .NET 3.5 RTM).

[XmlRoot("foo")]
public class Foo
{
    static void Main()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Foo));

        string xml = @"<foo name='ack' />";
        using (StringReader sr = new StringReader(xml))
        {
            Foo foo = serializer.Deserialize(sr) as Foo;
        }
    }

    [XmlAttribute("name")]
    public string Name { get; set; }

    public Foo Bar { get; private set; }
}

В SP1 приведенный выше код работает просто отлично. В RTM вы получаете исключение InvalidOperationException:

Невозможно создать временный класс (результат = 1). ошибка CS0200: Свойство или индексатор 'ConsoleApplication2.Foo.Bar' нельзя назначить - оно доступно только для чтения

Конечно, все, что нужно для запуска в RTM, - это добавить [XmlIgnore] в свойство Bar.

Мой гугл-фу, видимо, не может найти документацию о подобных изменениях. Есть ли где-нибудь список изменений, в котором перечислены эти изменения (и подобные скрытые изменения, которые могут подпрыгнуть и выкрикнуть «уловка»)? Это ошибка или особенность?

EDIT : если в SP1 добавить элемент <Bar /> или задать свойство [XmlElement] для свойства Bar, оно не будет десериализовано. Он не завершает работу до SP1 при попытке десериализации - он генерирует исключение при создании XmlSerializer.

Это заставляет меня больше склоняться к тому, чтобы это было ошибкой, особенно если я установил атрибут [XmlElement] для Foo.Bar. Если он не может сделать то, что я прошу, он должен генерировать исключение вместо того, чтобы молча игнорировать Foo.Bar. Другие недопустимые комбинации / настройки атрибутов сериализации XML приводят к исключению.

РЕДАКТИРОВАТЬ : Спасибо, TonyB, я бы не знал о настройке расположения временных файлов. Для тех, кто сталкивается с подобными проблемами в будущем, вам нужен дополнительный флаг конфигурации:

<system.diagnostics>
  <switches>
    <add name="XmlSerialization.Compilation" value="1" />
  </switches>
</system.diagnostics>
<system.xml.serialization>
  <xmlSerializer tempFilesLocation="c:\\foo"/>
</system.xml.serialization>

Даже при установке атрибута [XmlElement] в свойстве Bar его не упоминалось в сгенерированной сборке сериализации - что довольно твердо помещает это в область молча проглоченной ошибки (иначе, ошибка). Либо так, либо разработчики решили, что [XmlIgnore] больше не нужен для свойств, которые нельзя установить - и вы ожидаете увидеть это в примечаниях к выпуску, списки изменений или Документация XmlIgnoreAttribute .

Ответы [ 2 ]

4 голосов
/ 30 августа 2008

В SP1 правильно ли десериализуется свойство foo.Bar?

В до SP1 вы не смогли бы десериализовать объект, потому что метод set свойства Bar является приватным, поэтому у XmlSerializer нет способа установить это значение. Я не уверен, как SP1 справляется с этим.

Вы можете попробовать добавить это в ваш web.config / app.config

<system.xml.serialization> 
  <xmlSerializer tempFilesLocation="c:\\foo"/> 
</system.xml.serialization> 

Это поместит класс, сгенерированный XmlSerializer, в c: \ foo, чтобы вы могли видеть, что он делает в SP1 против RTM

0 голосов
/ 30 августа 2008

Мне скорее нравится это новое (?) Поведение, потому что в документе XML нет никакого упоминания о Bar, поэтому десериализатор даже не должен пытаться его установить.

...