Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML deserialization - throwing custom errors

So I have the following method:

private int? myIntField
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public int? IntField{
    get {
        return this.myIntField;
    }
    set {
        this.myIntField= value;
    }
 }

Now, I am deserializing xml from a post, if for whatever reason I am getting a string, such as "here is the int field: 55444" instead of 55444, the error I get in response is: Input string was not in a correct format. which isn't very specific, especially considering I will have more than one int field I need to verify.

Originally, I was planning something like this:

private string myIntField
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public int? IntField{
    get {
        return this.myIntField.CheckValue();
    }
    set {
        this.myIntField= value;
    }
 }

Where CheckValue performs a try-parse to an Int32, and if it fails it returns a null and adds an error to a list. However, I can't seem to nail this set-up for the generated classes.

Is there I way I can throw a specific error if I am getting strings in place of ints, DateTimes, etc?

like image 294
RJP Avatar asked Jul 15 '26 21:07

RJP


2 Answers

It's easy if you have schema(s) for you XML and validate it against schema before deserializing. Suppose you have schema(s) for your XML, you can initialize a XmlSchemaSet, add your schema(s) in it and the:

var document = new XmlDocument();
document.LoadXml(xml); // this a string holding the XML
document.Schemas.XmlResolver = null; //if you don't need to resolve every references
document.Schemas.Add(SchemaSet); // System.Xml.Schema.XmlSchemaSet instance filled with schemas
document.Validate((sender, args) => { ... }); //args are of type ValidationEventArgs and hold problem if there is one...            

Personally I think this is a better approach, because you can validate your XML before deserializing and be sure the XML is correct otherwise the deserializer will most probably throw an exception if something is wrong and you will almost never be able to show a meaningful feedback to the user...
P.S. I recommend creating schema(s) describing the XML

like image 59
graver Avatar answered Jul 18 '26 01:07

graver


The "Input string was not in a correct format" messages comes from a standard System.FormatException raised by a call to int.Parse, added to the automatically generated assembly that does the deserialization. I don't think you can add some custom logic to that.

One solution is to do something like this:

    [XmlElement("IntField")]
    [Browsable(false)] // not displayed in grids
    [EditorBrowsable(EditorBrowsableState.Never)] // not displayed by intellisense
    public string IntFieldString
    {
        get
        {
            return DoSomeConvert(IntField);
        }
        set
        {
            IntField = DoSomeOtherConvert(value);
        }
    }

    [XmlIgnore]
    public int? IntField { get; set; }

It's not perfect, because you can still get access to the public IntFieldString, but at least, the "real" IntField property is used only programmatically, but not by the XmlSerializer (XmlIgnore), while the field that's holding the value back & forth is hidden from programmers (EditorBrowsable), grids (Browsable), etc... but not from the XmlSerializer.

like image 36
Simon Mourier Avatar answered Jul 18 '26 02:07

Simon Mourier