By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,194 Members | 1,694 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,194 IT Pros & Developers. It's quick & easy.

System.Xml.XmlValidatingReader.set_ValidationType raised InvalidOperationException

P: n/a
I am using an XmlValidatingReader which uses an XSD for xml
validation. The code has been performing reliably for months.
Yesterday it failed for the first time with the following exception:

Inner exception of type System.InvalidOperationException has occurred
: The operation is not valid due to the current state of the object.
[source = System.Xml]
[method call = set_ValidationType]
[stack trace = at
System.Xml.XmlValidatingReader.set_ValidationType( ValidationType
value)

As I said, this code has been quite some time. It has been tested and
is now in a production system in a critical code path. When it failed
it caused a significant financial transaction to fail. I am wondering
if anyone has ever seen this behaviour or has any recommendations.

The offending code is as follows:

private static XmlValidatingReader vReader = null;
private static XmlSchemaCollection xsc = new XmlSchemaCollection();
// . . .
StringReader sr = new StringReader(xsdString);
XmlTextReader schemaReader = new XmlTextReader(sr);
xsc.Add(null, schemaReader);
// . . .
vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;
Nov 12 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
This exception would be caused when the ReadState of the validaitng reader
is not set to ReadState.Initial, which imples that the validating reader was
moved ahead( via a call to Read() ) before setting the ValidationType
property.

Could you share your original code and data files?

Thanks.
Zafar
"Jesse Elve" <je********@t4g.com> wrote in message
news:23**************************@posting.google.c om...
I am using an XmlValidatingReader which uses an XSD for xml
validation. The code has been performing reliably for months.
Yesterday it failed for the first time with the following exception:

Inner exception of type System.InvalidOperationException has occurred
: The operation is not valid due to the current state of the object.
[source = System.Xml]
[method call = set_ValidationType]
[stack trace = at
System.Xml.XmlValidatingReader.set_ValidationType( ValidationType
value)

As I said, this code has been quite some time. It has been tested and
is now in a production system in a critical code path. When it failed
it caused a significant financial transaction to fail. I am wondering
if anyone has ever seen this behaviour or has any recommendations.

The offending code is as follows:

private static XmlValidatingReader vReader = null;
private static XmlSchemaCollection xsc = new XmlSchemaCollection();
// . . .
StringReader sr = new StringReader(xsdString);
XmlTextReader schemaReader = new XmlTextReader(sr);
xsc.Add(null, schemaReader);
// . . .
vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;

Nov 12 '05 #2

P: n/a
Zafar:

This has turned out to be a very interesting bug. I will be very pleased if
anyone will agree with me that the only possible cause is due to multiple
threads accessing the function simultaneously. (My supervisor thinks that
I'm jumping to this conclusion too hastily!)

In any event, the exception was raised on the final line of the following
code excerpt (!):

vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;

Note that this is an _exact_ excerpt. As you can see, there is _no_
possibility that "read" is called before the "ValidationType" is set, as the
reader has just been instantiated 2 lines up!

This becomes more interesting when the full class is considered:

-------------------------------------------------------------------------
public class OrderValidator
{
private static XmlValidatingReader vReader = null;
private static XmlSchemaCollection xsc = new XmlSchemaCollection();

private OrderValidator()
{
// Access XSD as an embedded resource in this assembly:
System.Reflection.Assembly myAssembly;
myAssembly = System.Reflection.Assembly.GetExecutingAssembly();
System.Resources.ResourceManager myManager = new
System.Resources.ResourceManager("xxx.xxx.xxx.xxx. Order_XSD",
myAssembly);
string xsdString =
myManager.GetString("Order_xsd",System.Globalizati on.CultureInfo.InvariantCu
lture); // this is case-sensitive
StringReader sr = new StringReader(xsdString);
XmlTextReader schemaReader = new XmlTextReader(sr);

// Add XSD to schemaCollection
xsc.Add(null, schemaReader);
}

/// <summary>
/// Singleton instance via .NET-Framework-managed singleton semantics
/// </summary>
public static readonly OrderValidator Instance = new OrderValidator();

/// <summary>
/// Validation method
/// </summary>
/// <param name="candidate">fresh XMLTextReader (unread!)</param>
/// <returns>true for valid XML or throws an exception for
failure</returns>
public Boolean Validates(XmlTextReader candidate)
{
Boolean isValid = false;
vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;
try
{
while (vReader.Read()){}
isValid = true;
}
catch(Exception e)
{
string message = "Validation failed: ";
message += "Element name: " + (vReader.Name != null ? vReader.Name :
String.Empty) + ". ";
message += "Element value: " + (vReader.Value != null ? vReader.Value :
String.Empty) + ". ";
throw(new ApplicationException(message, e));
}
return isValid;
}

}
-------------------------------------------------------------------------

There were numerous factors which made it logical to design this class as a
Singleton, chiefly the size and complexity of the XSD. Once instantiated,
the singleton instance of this class does service validation requests from
multiple threads.

The only explanation that I can come up with is that 2 contending threads
are in the "Validates" method simultaneously. I'm very open to any other
explanation!

In the meantime, I have already implemented the following modifications
based on my "thread contention" theory:

--------------------------------------------------------------------------

// object used for method-level locking
private static Object privateStaticObject = new Object();

public Boolean Validates(XmlTextReader candidate)
{
Boolean isValid = false;
lock (privateStaticObject)
{
vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;
try
{
while (vReader.Read()){}
isValid = true;
}
catch(Exception e)
{
string message = "Validation failed: ";
message += "Element name: " + (vReader.Name != null ? vReader.Name :
String.Empty) + ". ";
message += "Element value: " + (vReader.Value != null ? vReader.Value :
String.Empty) + ". ";
throw(new ApplicationException(message, e));
}
}
return isValid;
}

--------------------------------------------------------------------------

Based on a previous incident, however, our architect thinks I'm too quick to
jump to a "thread contention" conclusion. If anyone has any other
interpretations or suggestions please let me know!
Nov 12 '05 #3

P: n/a
Definitely looks like a thread contention issue since your original code has
vReader as a static variable and you have no locks around the code. Locking
the code for the entire validation period is expensive and basically loses
all the benefits of using multiple threads. The simple answer is for vReader
not to be a static member variable.

--
This posting is provided "AS IS" with no warranties, and confers no rights.

"Jesse Elve" <je********@t4g.com> wrote in message
news:ul**************@TK2MSFTNGP11.phx.gbl...
Zafar:

This has turned out to be a very interesting bug. I will be very pleased if anyone will agree with me that the only possible cause is due to multiple
threads accessing the function simultaneously. (My supervisor thinks that
I'm jumping to this conclusion too hastily!)

In any event, the exception was raised on the final line of the following
code excerpt (!):

vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;

Note that this is an _exact_ excerpt. As you can see, there is _no_
possibility that "read" is called before the "ValidationType" is set, as the reader has just been instantiated 2 lines up!

This becomes more interesting when the full class is considered:

-------------------------------------------------------------------------
public class OrderValidator
{
private static XmlValidatingReader vReader = null;
private static XmlSchemaCollection xsc = new XmlSchemaCollection();

private OrderValidator()
{
// Access XSD as an embedded resource in this assembly:
System.Reflection.Assembly myAssembly;
myAssembly = System.Reflection.Assembly.GetExecutingAssembly();
System.Resources.ResourceManager myManager = new
System.Resources.ResourceManager("xxx.xxx.xxx.xxx. Order_XSD",
myAssembly);
string xsdString =
myManager.GetString("Order_xsd",System.Globalizati on.CultureInfo.InvariantCu lture); // this is case-sensitive
StringReader sr = new StringReader(xsdString);
XmlTextReader schemaReader = new XmlTextReader(sr);

// Add XSD to schemaCollection
xsc.Add(null, schemaReader);
}

/// <summary>
/// Singleton instance via .NET-Framework-managed singleton semantics
/// </summary>
public static readonly OrderValidator Instance = new OrderValidator();

/// <summary>
/// Validation method
/// </summary>
/// <param name="candidate">fresh XMLTextReader (unread!)</param>
/// <returns>true for valid XML or throws an exception for
failure</returns>
public Boolean Validates(XmlTextReader candidate)
{
Boolean isValid = false;
vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;
try
{
while (vReader.Read()){}
isValid = true;
}
catch(Exception e)
{
string message = "Validation failed: ";
message += "Element name: " + (vReader.Name != null ? vReader.Name :
String.Empty) + ". ";
message += "Element value: " + (vReader.Value != null ? vReader.Value : String.Empty) + ". ";
throw(new ApplicationException(message, e));
}
return isValid;
}

}
-------------------------------------------------------------------------

There were numerous factors which made it logical to design this class as a Singleton, chiefly the size and complexity of the XSD. Once instantiated,
the singleton instance of this class does service validation requests from
multiple threads.

The only explanation that I can come up with is that 2 contending threads
are in the "Validates" method simultaneously. I'm very open to any other
explanation!

In the meantime, I have already implemented the following modifications
based on my "thread contention" theory:

--------------------------------------------------------------------------

// object used for method-level locking
private static Object privateStaticObject = new Object();

public Boolean Validates(XmlTextReader candidate)
{
Boolean isValid = false;
lock (privateStaticObject)
{
vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;
try
{
while (vReader.Read()){}
isValid = true;
}
catch(Exception e)
{
string message = "Validation failed: ";
message += "Element name: " + (vReader.Name != null ? vReader.Name :
String.Empty) + ". ";
message += "Element value: " + (vReader.Value != null ? vReader.Value : String.Empty) + ". ";
throw(new ApplicationException(message, e));
}
}
return isValid;
}

--------------------------------------------------------------------------

Based on a previous incident, however, our architect thinks I'm too quick to jump to a "thread contention" conclusion. If anyone has any other
interpretations or suggestions please let me know!

Nov 12 '05 #4

P: n/a
Thanks,

In retrospect, that seems obvious!
"Dare Obasanjo [MSFT]" <da***@online.microsoft.com> wrote in message
news:OH**************@TK2MSFTNGP15.phx.gbl...
Definitely looks like a thread contention issue since your original code has vReader as a static variable and you have no locks around the code. Locking the code for the entire validation period is expensive and basically loses
all the benefits of using multiple threads. The simple answer is for vReader not to be a static member variable.

--
This posting is provided "AS IS" with no warranties, and confers no rights.
"Jesse Elve" <je********@t4g.com> wrote in message
news:ul**************@TK2MSFTNGP11.phx.gbl...
Zafar:

This has turned out to be a very interesting bug. I will be very pleased
if
anyone will agree with me that the only possible cause is due to
multiple threads accessing the function simultaneously. (My supervisor thinks that I'm jumping to this conclusion too hastily!)

In any event, the exception was raised on the final line of the following code excerpt (!):

vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;

Note that this is an _exact_ excerpt. As you can see, there is _no_
possibility that "read" is called before the "ValidationType" is set, as

the
reader has just been instantiated 2 lines up!

This becomes more interesting when the full class is considered:


-------------------------------------------------------------------------
public class OrderValidator
{
private static XmlValidatingReader vReader = null;
private static XmlSchemaCollection xsc = new XmlSchemaCollection();

private OrderValidator()
{
// Access XSD as an embedded resource in this assembly:
System.Reflection.Assembly myAssembly;
myAssembly = System.Reflection.Assembly.GetExecutingAssembly();
System.Resources.ResourceManager myManager = new
System.Resources.ResourceManager("xxx.xxx.xxx.xxx. Order_XSD",
myAssembly);
string xsdString =

myManager.GetString("Order_xsd",System.Globalizati on.CultureInfo.InvariantCu
lture); // this is case-sensitive
StringReader sr = new StringReader(xsdString);
XmlTextReader schemaReader = new XmlTextReader(sr);

// Add XSD to schemaCollection
xsc.Add(null, schemaReader);
}

/// <summary>
/// Singleton instance via .NET-Framework-managed singleton semantics
/// </summary>
public static readonly OrderValidator Instance = new OrderValidator();

/// <summary>
/// Validation method
/// </summary>
/// <param name="candidate">fresh XMLTextReader (unread!)</param>
/// <returns>true for valid XML or throws an exception for
failure</returns>
public Boolean Validates(XmlTextReader candidate)
{
Boolean isValid = false;
vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;
try
{
while (vReader.Read()){}
isValid = true;
}
catch(Exception e)
{
string message = "Validation failed: ";
message += "Element name: " + (vReader.Name != null ? vReader.Name :
String.Empty) + ". ";
message += "Element value: " + (vReader.Value != null ? vReader.Value :
String.Empty) + ". ";
throw(new ApplicationException(message, e));
}
return isValid;
}

}
-------------------------------------------------------------------------

There were numerous factors which made it logical to design this class

as a
Singleton, chiefly the size and complexity of the XSD. Once
instantiated, the singleton instance of this class does service validation requests from multiple threads.

The only explanation that I can come up with is that 2 contending threads are in the "Validates" method simultaneously. I'm very open to any other explanation!

In the meantime, I have already implemented the following modifications
based on my "thread contention" theory:


--------------------------------------------------------------------------

// object used for method-level locking
private static Object privateStaticObject = new Object();

public Boolean Validates(XmlTextReader candidate)
{
Boolean isValid = false;
lock (privateStaticObject)
{
vReader = new XmlValidatingReader(candidate);
vReader.Schemas.Add(xsc);
vReader.ValidationType = ValidationType.Schema;
try
{
while (vReader.Read()){}
isValid = true;
}
catch(Exception e)
{
string message = "Validation failed: ";
message += "Element name: " + (vReader.Name != null ? vReader.Name : String.Empty) + ". ";
message += "Element value: " + (vReader.Value != null ?

vReader.Value :
String.Empty) + ". ";
throw(new ApplicationException(message, e));
}
}
return isValid;
}

--------------------------------------------------------------------------

Based on a previous incident, however, our architect thinks I'm too

quick to
jump to a "thread contention" conclusion. If anyone has any other
interpretations or suggestions please let me know!


Nov 12 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.