Могу ли я отказаться от десериализации с XmlSerializer в С#, если элемент не найден?

Я использую XmlSerializer для записи и чтения объекта в xml в С#. В настоящее время я использую атрибуты XmlElement и XmlIgnore для управления сериализацией объекта.

Если в моем XML файле отсутствует требуемый элемент xml, мой объект по-прежнему десериализует (xml → объект) просто отлично. Как указать (желательно через атрибуты), что определенное поле "требуется"?

Вот пример метода, который я использую в настоящее время:

[XmlElement(ElementName="numberOfWidgets")]
public int NumberThatIsRequired {
    set ...;
    get ...;
}

Моим идеальным решением было бы добавить что-то вроде атрибута XmlRequired.

Кроме того, есть ли хорошая ссылка на то, какие атрибуты доступны для управления поведением XmlSerializer?

Ответы

Ответ 1

У меня есть ответ для второй части: "Атрибуты, которые управляют сериализацией XML" .

Продолжая расследование первой части...

EDIT: Я сильно подозреваю, что вы не можете сделать это через само десериализацию XML. Я только что запустил xsd.exe в примерной схеме, которая включает в себя требуемый атрибут - и это точно так же, если атрибут помечен как необязательный. Если бы был задан способ установки свойств, я бы ожидал, что он будет реализован в этом случае.

Я подозреваю, что вам удалось просто проверить свое дерево объектов после десериализации. Извините за это...

Ответ 2

Единственный способ, которым я нашел это, - это использовать XSD. Что вы можете сделать, это проверить, пока вы deserialize:

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);
}

Ответ 3

По причинам расширяемости XmlSerializer очень прощает, когда дело доходит до десериализации; такие вещи, как [DefaultValue], ShouldSerialize{Foo} и {Foo}Specified, в основном используются во время сериализации (исключение составляет {Foo}Specified, которое устанавливается во время десериализации, а также запрашивается при сериализации).

Как таковой; нет простого способа сделать это, если вы не реализуете IXmlSerializable и не делаете это сами. damagednoob показывает параметр xsd, который также является опцией.