Я использую XmlSerializer для записи и чтения объекта в xml на C#. В настоящее время я использую атрибуты XmlElement и XmlIgnore для управления сериализацией объекта.
Если в моем XML-файле отсутствует элемент xml, который мне нужен, мой объект все равно десериализуется (xml -> объект) нормально. Как мне указать (желательно с помощью атрибутов), что определенное поле является «обязательным»?
Вот пример того, что я использую в настоящее время:
[XmlElement(ElementName = "numberOfWidgets")]
public int NumberThatIsRequired {
set ...;
get ...;
}
Моим идеальным решением было бы добавить что-то вроде атрибута XmlRequired.
Кроме того, есть ли хорошая ссылка на то, какие атрибуты доступны для управления поведением XmlSerializer?
если у вас нет элемента numberOfWidgets в XML, что будет у вас в свойстве NumberThatIsRequired? нуль?





У меня есть ответ на вторую часть: «Атрибуты, управляющие сериализацией XML».
Все еще исследуем первую часть ...
Обновлено: Я сильно подозреваю, что вы не можете сделать это через саму десериализацию XML. Я только что запустил xsd.exe на примере схемы, которая включает обязательный атрибут - и это будет точно так же, если атрибут отмечен как необязательный. Если бы существовал способ требовать установки свойств, я бы ожидал, что он будет реализован в этом случае.
Я подозреваю, что вам нужно просто проверить свое дерево объектов после его десериализации. Прости за это...
Вам необходимо правильно настроить пространство имен XML в исходном XML, на который также ссылается ваш XSD, иначе проверка с использованием XSD не будет работать должным образом, включая проверку обязательного поля.
Я нашел единственный способ сделать это - через XSD. Что вы можете сделать, так это проверить во время десериализации:
static T Deserialize<T>(string xml, XmlSchemaSet schemas)
{
//List<XmlSchemaException> exceptions = new List<XmlSchemaException>();
ValidationEventHandler validationHandler = (s, e) =>
{
//you could alternatively catch all the exceptions
//exceptions.Add(e.Exception);
throw e.Exception;
};
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(schemas);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += validationHandler;
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader sr = new StringReader(xml))
using (XmlReader books = XmlReader.Create(sr, settings))
return (T)serializer.Deserialize(books);
}
По причинам расширяемости XmlSerializer очень снисходителен к десериализации; такие вещи, как [DefaultValue], ShouldSerialize{Foo} и {Foo}Specified, являются в основном, используемыми во время сериализация (исключение составляет {Foo}Specified, который устанавливается во время десериализации, а также запрашивается во время сериализации).
Как таковой; нет простого способа сделать это, если вы не реализуете IXmlSerializable и не сделаете это сами. Damagednoob показывает опцию xsd, которая также является опцией.
DefaultValue имеет по крайней мере один важный эффект во время десериализации. Если элемент пустой, без DefaultValue может возникнуть ошибка синтаксического анализа. Однако при этом сгенерированный код пропустит пустой элемент.
Аналогичный вопрос msdn здесь, который также объясняет, что проверка - это то, что вы пытаетесь сделать