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

3

15

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?

Haematothermal answered 3/11, 2008 at 19:56 Comment(2)
Similar msdn question here which also explains that validation is what you are trying to doMordent
if you don't have the element numberOfWidgets in the XML, what will you have in the property NumberThatIsRequired? zero?Angio
F
5

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

Fideicommissum answered 3/11, 2008 at 19:58 Comment(1)
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.Christianism
P
16

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);
}
Piezoelectricity answered 3/11, 2008 at 21:10 Comment(0)
F
5

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

Fideicommissum answered 3/11, 2008 at 19:58 Comment(1)
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.Christianism
F
4

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.

Farica answered 4/11, 2008 at 5:10 Comment(1)
DefaultValue has at least one important effect during deserialization. If the element is empty, without DefaultValue there may be a parsing error. However, with it, the generated code will skip the empty element.Reamonn

© 2022 - 2024 — McMap. All rights reserved.