Сгенерированный класс Xsd.exe не сериализует обязательные элементы при нулевом значении

В следующем XSD все элементы являются обязательными:

<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns="http://TestNamespace" xmlns:b="http://schemas.microsoft.com/BizTalk/2003" targetNamespace="http://TestNamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Test">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="1" maxOccurs="1" name="Id" type="xs:int" />
        <xs:element minOccurs="1" maxOccurs="1" name="EMail" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Однако, когда я сериализую экземпляр сгенерированного xsd.exe класса, где EMail == null, результирующий XML недействителен в соответствии со схемой, поскольку элемент EMail полностью отсутствует.

<?xml version="1.0"?>
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://TestNamespace">
  <Id xmlns="">2</Id>
</Test>

Это почему? Есть ли способ предотвратить это?


person metalheart    schedule 24.04.2015    source источник
comment
Что вы действительно спрашиваете? Сериализатор делает единственную логичную вещь, поскольку вы действительно передали значение NULL. Вы спрашиваете, почему сериализатор также не проверяет результат? Вы хотите предотвратить сериализацию недопустимых классов? Проверять классы перед сериализацией?   -  person Panagiotis Kanavos    schedule 24.04.2015
comment
хорошо, поскольку я сгенерировал класс с помощью инструмента, я ожидаю, что результаты будут действительными автоматически, т.е. в этом случае сериализатор должен добавить пустой элемент ‹EMail /› - так что мой вопрос в том, как этого добиться?   -  person metalheart    schedule 24.04.2015


Ответы (1)


В своих комментариях вы упоминаете, что хотите, чтобы пустое значение использовалось по умолчанию для отсутствующего элемента Email.

Это проблема на уровне схемы, не связанная с сериализатором или генератором прокси.

Такое поведение должно быть определено в схеме, а не оставлено на усмотрение сериализатора. К сожалению, XML-схема не допускает значения элементов по умолчанию, потому что это далеко слишком сложный, чтобы угадать, какой будет структура элемента по умолчанию. Есть ли в нем необходимые элементы? Массивы? А как насчет элементов выбора?

XML-схема разрешает использовать значения атрибутов по умолчанию или фиксированные значения являются разрешены хотя, используя атрибуты default и fixed.

Одним из решений является создание экземпляра того, что вы считаете допустимым пустым объектом Email, и использование его вместо нулевых значений.

static readonly EmptyEmail=new Email();
...
test.Email=test.Email??EmptyEmail;

На самом деле, это один из случаев шаблона Null Object — используйте экземпляр Null Object вместо нулевые значения. Многие классы .NET Framework хранят объект Null в виде статического поля только для чтения с именем Empty в самом классе. Это делает код немного чище:

test.Email=test.Email??Email.Empty;

Другой вариант — инициализировать свойство Email в конструкторе класса. Сгенерированные XSD классы являются частичными, что позволяет вам определить конструктор в частичном файле, который не будет перезаписан при повторном создании прокси-сервера, например:

public partial class Test 
{
    public Test()
    {
        Email=new Email();
    }

}
person Panagiotis Kanavos    schedule 24.04.2015