简体   繁体   中英

Can I fail to deserialize with XmlSerializer in C# if an element is not found?

I am using XmlSerializer to write and read an object to xml in C#. I currently use the attributes XmlElement and XmlIgnore to manipulate the serialization of the object.

If my xml file is missing an xml element that I require, my object still deserializes (xml -> object) just fine. How do I indicate (preferably via Attributes) that a certain field is "required"?

Here is a sample method of what I am using currently:

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

My ideal solution would be to add something like an XmlRequired attribute.

Also, is there a good reference for what Attributes are available to manipulate the behavior of XmlSerializer?

The only way I've found to do this is via XSD. What you can do is validate while you 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);
}

I've got an answer for the second part: "Attributes that control XML serialization" .

Still investigating the first part...

EDIT: I strongly suspect you can't do this through XML deserialization itself. I've just run xsd.exe on a sample schema which includes a required attribute - and it's exactly the same if the attribute is marked as being optional. If there were a way of requiring properties to be set, I'd expect it to be implemented in that case.

I suspect you've basically got to just validate your tree of objects after deserializing it. Sorry about that...

For extensibility reasons, XmlSerializer is very forgiving when it comes to deserialization; things like [DefaultValue] , ShouldSerialize{Foo} and {Foo}Specified are mainly used during serialization (the exception being {Foo}Specified , which is set during deserialization as well as queried during serialization).

As such; there isn't an easy way to do this, unless you implement IXmlSerializable and do it yourself. Richard shows an xsd option, which is also an option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM