Вопрос

Я видел довольно много сообщений об изменениях в .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.

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

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

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

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

<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 .

Это было полезно?

Решение

В 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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top