Samstag, 15. Mai 2010

Failed XML Validation of integer values

I recently came around a strange issue while validating a xml file. The content looked similar to this one:

<main xmlns="http://tempuri.org/myNamespace">
<number>298660059755687851616176132193422926953</number>
<note>Test</note>
</main>

While validating this file using C# .NET 3.5 I received the following error within the ValidationEventHandler:

"Das Element 'http://tempuri.org/myNamespace:Number' hat gemäß seinem Datentyp einen ungültigen Wert."


The element itself is specified within the schema file:

<xs:element name="Number" type="xs:integer"/>

A quick research about the "xs:integer" data type showed, that an integer value within xml is unbounded. Due to limitations of our beloved working machines integers are limited in most frameworks (e.g. 2.147.483.647 for Int32 in .NET).

My dilemma was that I wanted to use the build-in validation mechanism with elements containing integers exceeding the framework bounds.

So the key was to check what causes a validation failure and if this failure was "wrong" due to the framework limitations. The following will roughly sketch the solution to this.

Within the ValidationEventHandler a method named "IsWrongFormatException" is called to check if the error can be ignored:

private void ValidatingReader_ValidationEventHandler(object sender, ValidationEventArgs e)
// check if the error is a wrong format exception
if(!IsWrongFormatException(sender, e)) {
// tread as "correct" error
}
}

When the value exceeds the framework bounds a FormatException is thrown. This exception will be placed in the InnerException property of the ValidationEventArgs argument. So we have to check if the error was caused by a FormatException:

private bool IsWrongFormatException(object sender, ValidationEventArgs e) {
// check for non null Exception-Property
// Get the inner Exception
FormatException exception = e.Exception.InnerException as FormatException;
// check if is a FormatException
if (null != exception) {

If the exception is not null, we know a FormatException occured. The type used to check the format of the value is stored in the sender object (in a property named "ValueType"). I used reflection here to get the PropertyInfo and the value of the property.

// use reflection to get the info
PropertyInfo infoValueType = sender.GetType().GetProperty("ValueType");
// read the validated value type
Type valueType = infoValueType.GetValue(sender, null) as Type;

For validating integer values the framework uses the Decimal-class. So we check if the type equals Decimal.

if ((null != valueType) && (valueType.Equals(typeof (Decimal)))) {

Now we know that a FormatException occured within an xml element that should contain an integer value. It would be easy to ignore the error at this point, but it could be possible that the value is really invalid (e.g. containing a character). So we need the value that was validated itself. This is more difficult because the text (containing the value) is burried as a non-public property of the sender. But reflection will help us at this moment. First we read the property "validator" of the sender

FieldInfo info = sender.GetType().GetField("validator", BindingFlags.Instance | BindingFlags.NonPublic);
object validator = info.GetValue(sender);

The validator object contains the property "textValue" with the searched string:

info = validator.GetType().GetField("textValue", BindingFlags.Instance | BindingFlags.NonPublic);
StringBuilder textValue = info.GetValue(validator) as StringBuilder;

The StringBuilder named textValue contains the validated value. To check if the value is a valid integer we use a regular expression to check.

result = ((null != value) && (System.Text.RegularExpressions.Regex.IsMatch(textValue.ToString(), "^[0-9]+$")));

If result is true, then the FormatException was thrown wrongly during the validation and we can ignore the error.

Remarks:
I read that there is a special xml datatype named xs:int to reflect bounded integer values.

Sonntag, 7. Dezember 2008

First article on CodeProject

After a long while of absence I am here to announce my first article on CodeProject. The article describes how to use custom attributes and AOP in c# to implement a permission management for business logics. Have a look and enjoy reading.

You can find the article here.

Dienstag, 21. Oktober 2008

Getting started

Console.Out.WriteLine("Hello World!");

So here i am, writing my first posting for my own blog. Took me quite a while to find a blog provider for free, while looking decent and trustable. As you can see I finally made it to Blogger.com.

So what will this blog be about? (Beside the effect learning to write good english...) Like the title is saying it, me in the wide world of software. I'm currently working a lot with the .NET Framework, and what should I say: I'm lovin it! But this blog will be more than another MS Advertisement, it should touch nearly all topics around software i'm dealing with the whole day.

So let's get it on!