views:

1405

answers:

3

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?

+2  A: 

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...

Jon Skeet
You do need to have an XML namespace properly set up in your source XML which is also referenced in your XSD, or validation using an XSD will not work properly, including required field validation.
Robert Harvey
+2  A: 

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);
}
Richard Nienaber
A: 

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. damagednoob shows an xsd option, which is also an option.

Marc Gravell