Вопрос

У меня есть свойство, определенное как:

[XmlArray("delete", IsNullable = true)]
[XmlArrayItem("contact", typeof(ContactEvent)),
 XmlArrayItem("sms", typeof(SmsEvent))]
public List<Event> Delete { get; set; }

Если список<> Удалить не содержит элементов

<delete />

испускается.Если список<> Для параметра Delete установлено значение null

<delete xsi:nil="true" />

испускается.Есть ли способ, используя атрибуты, заставить элемент delete не генерироваться, если в коллекции нет элементов?

Грег - Отлично, спасибо, я даже не читал документацию IsNullable, просто предположил, что она сигнализирует об этом как о необязательном.

Роб Купер - Я пытался избежать ISerializable, но предложение Gregs работает.Я действительно столкнулся с проблемой, которую вы описали в (1), я сломал кучу кода, просто вернув null, если коллекция имела нулевую длину.Чтобы обойти это, я создал класс EventsBuilder (класс, который я сериализую, называется Events ), который управлял всем временем жизни / созданием базовых объектов класса Events, который использует наши классы Events для сериализации.

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

Решение

Если вы установите IsNullable=false или просто удалите его (по умолчанию оно равно false), то элемент "удалить" не будет выдан.Это будет работать только в том случае, если коллекция равна null.

Я предполагаю, что существует путаница между "обнуляемостью" в терминах .NET и путаницей, связанной с обнуляемыми элементами в XML - теми, которые отмечены атрибутом xml: nil .XmlArrayAttribute.Свойство IsNullable управляет последним.

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

У меня была такая же проблема, когда я не хотел, чтобы элемент выводился, если поле пустое или 0.Выведенный XML-файл не мог использовать xsi: null="true" (по замыслу).

Я где-то читал, что если вы включаете свойство типа bool с тем же именем, что и поле, которым вы хотите управлять, но добавляете "Указанное", XmlSerializer проверит возвращаемое значение этого свойства, чтобы определить, следует ли включать соответствующее поле.

Чтобы достичь этого без внедрения IXMLSerializer:

public List<Event> Delete { get; set; }
[XMLIgnore]
public bool DeleteSpecified
{
 get
 {
   bool isRendered = false;
   if (Delete != null)
   {
     isRendered = (Delete.Count > 0);
   } 

   return isRendered;
 }
 set
 {
 }
}

Прежде всего, я бы сказал, спросите себя ".Что такое сериализация?".

Тот Самый XmlSerializer - сериализатор делает именно то, что он должен делать, сохраняя текущее состояние объекта в формате XML.Теперь я не уверен, почему текущее поведение не является "правильным" для вас, поскольку, если вы инициализировали список, то он является инициализирован.

Я думаю, что здесь у вас есть три варианта:

  1. Добавьте код в средство получения, чтобы возвращать значение null, если в коллекции 0 элементов.Однако это может испортить другой имеющийся у вас код.
  2. Внедрить Ixmlсериализуемый подключайте интерфейс и делайте всю работу самостоятельно.
  3. Если это обычный процесс, то вы, возможно, захотите взглянуть на мой вопрос "Сериализация XML и унаследованные типы" - Да, я знаю, что это касается другой проблемы, но это показывает вам, как создать универсальный промежуточный класс сериализации, который затем можно "прикрутить", чтобы позволить инкапсулировать процесс серилизации.Вы могли бы создать аналогичный класс, чтобы справиться с переопределением процесса по умолчанию для коллекций с нулевым значением / нулевыми элементами.

Я надеюсь, что это поможет.

Вы всегда можете реализовать IXmlSerializer и выполнить сериализацию вручную.

Видишь http://www.codeproject.com/KB/cs/IXmlSerializable.aspx для примера.

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