Microsoft KB Archive/811107

= ADO.NET limitation in validating XSD facets =

Article ID: 811107

Article Last Modified on 3/9/2006

-

APPLIES TO


 * Microsoft .NET Framework 1.1 Service Pack 1
 * Microsoft ADO.NET 2.0

-



SYMPTOMS
ADO.NET does not throw any exceptions when it validates data that is newly inserted or modified in a DataRow. This is true if the DataRow violates XSD facets that are defined in an underlying XSD schema of the DataSet object.



CAUSE
ADO.NET currently validates only the length and maxLength facets for the XSD string primitive data type. All other XSD facets are ignored by ADO.NET when it validates data that is newly inserted or modified in a DataRow.



RESOLUTION
This is currently a known limitation in ADO.NET.

You can work around this problem by using a System.Xml.XmlValidatingReader object to validate the XML representation of the data in a DataSet against its underlying schema.



STATUS
This behavior is by design.



Steps to Reproduce the Behavior
  Use the following schema to create and save an XSD schema named Employee.xsd to the root folder of your hard disk: 



    

  <xs:minInclusive value=&quot;18&quot;/> <xs:maxInclusive value=&quot;50&quot;/> </xs:restriction> </xs:simpleType>

<xs:complexType name=&quot;EmployeeType&quot;> <xs:sequence> <xs:element name=&quot;EmployeeID&quot; type=&quot;xs:string&quot;/> <xs:element name=&quot;FirstName&quot; type=&quot;xs:string&quot;/> <xs:element name=&quot;MiddleInitial&quot; type=&quot;InitialType&quot;/> <xs:element name=&quot;LastName&quot; type=&quot;xs:string&quot;/> <xs:element name=&quot;age&quot; type=&quot;AgeType&quot;/> </xs:sequence> </xs:complexType>

</xs:schema> </li> <li>Using the Visual Studio .NET IDE, create a new Visual Basic .NET console application or use the Visual Studio 2005 IDE to create a new Visual Basic 2005 console application.</li> <li> In Module1.vb, paste the following code in Sub Main: Dim response As String Try Dim dsEmployees As System.Data.DataSet dsEmployees = New DataSet

Dim employeeTable As System.Data.DataTable

dsEmployees.ReadXmlSchema(&quot;c:\Employee.xsd&quot;)

employeeTable = dsEmployees.Tables(&quot;Employee&quot;)

Dim employeeRow As System.Data.DataRow employeeRow = employeeTable.NewRow

employeeRow(&quot;EmployeeID&quot;) = &quot;E1&quot; employeeRow(&quot;FirstName&quot;) = &quot;Jim&quot; employeeRow(&quot;MiddleInitial&quot;) = &quot;AH&quot; employeeRow(&quot;LastName&quot;) = &quot;Stanton&quot; employeeRow(&quot;age&quot;) = 60

employeeTable.Rows.Add(employeeRow) Console.WriteLine(&quot;Row was added successfully&quot;) Catch ArgException As System.ArgumentException Console.WriteLine(&quot;Error occurred : &quot; & ArgException.Message) Finally response = Console.ReadLine End Try </li> <li>Build and run the application.

A System.ArgumentException is raised by the line of code that tries to add the invalid row to the Employee DataTable. The catch block displays the following error message that indicates that a value that is not valid was assigned to the MiddleInitial column:

Error occurred : Cannot set column 'MiddleInitial' to 'AH'. The value violates the MaxLength limit of this column.

</li> <li> Press any key to quit the program, and then change the value assigned to the MiddleInitial column to a single character &quot;A&quot;, as shown in the following line of code: employeeRow(&quot;MiddleInitial&quot;) = &quot;A&quot; </li> <li>Save, re-build, and then run the program. The

Row was successfully added

message appears in the Console window, indicating that the record was successfully added to the Employee DataTable without generating an exception to reflect that a value that is not valid is assigned to the Age column.</li></ol>

<div class="workaround_section">

WORKAROUND
To work around this problem, use a System.Xml.XmlValidatingReader object to validate the XML representation of the data in a DataSet against its underlying schema. <ol> <li>In Module1.vb, delete the existing code in Sub Main.</li> <li> In Module1.vb, paste the following code in Sub Main. Study the in-line comments that explain the newly added code to validate the XML representation of the data in the DataSet by using a System.Xml.XmlValidatingReader object: Dim response As String Try Dim dsEmployees As System.Data.DataSet dsEmployees = New DataSet

Dim employeeTable As System.Data.DataTable

dsEmployees.ReadXmlSchema(&quot;c:\employee.xsd&quot;)

employeeTable = dsEmployees.Tables(&quot;Employee&quot;)

Dim employeeRow As System.Data.DataRow employeeRow = employeeTable.NewRow

employeeRow(&quot;EmployeeID&quot;) = &quot;E1&quot; employeeRow(&quot;FirstName&quot;) = &quot;Jim&quot; employeeRow(&quot;MiddleInitial&quot;) = &quot;A&quot; employeeRow(&quot;LastName&quot;) = &quot;Stanton&quot; employeeRow(&quot;age&quot;) = 60

dsEmployees.Tables(&quot;Employee&quot;).Rows.Add(employeeRow)

'Write out the Dataset's schema to disk. dsEmployees.WriteXmlSchema(&quot;c:\dsEmployeesSchema.xsd&quot;)

'Create an instance of an XmlValidatingReader to parse the XML representation of the Dataset's data '(obtained by calling the GetXml method of the Dataset.           Dim rdr As New System.Xml.XmlValidatingReader(dsEmployees.GetXml, System.Xml.XmlNodeType.Element, Nothing)

'Add an event handler to trap validation errors. AddHandler rdr.ValidationEventHandler, AddressOf ValidationEvent

'Create an instance of an XmlSchemaCollection object to cache the dataset's schema. Dim sc As New System.Xml.Schema.XmlSchemaCollection rdr.ValidationType = Xml.ValidationType.Schema

'Add the XmlSchemaCollection to the XmlValidatingReaders schemas collection. rdr.Schemas.Add(Nothing, &quot;c:\dsEmployeesSchema.xsd&quot;)

'Parse the XML data. 'Any validation errors experienced are trapped and reported by the 'ValidationEvent custom sub procedure that implements the System.Xml.Schema.ValidationEventHandler delegate. Do While rdr.Read

Loop

Catch exp As Exception Console.WriteLine(&quot;Error occurred : &quot; & exp.Message) Finally response = Console.ReadLine End Try </li> <li> Add the following ValidationEvent custom Sub procedure to Module1.

This procedure is an implementation of the System.Xml.Schema.ValidationEventHandler delegate. It is linked to the ValidationEventHandler event of the XmlValidatingReader object by the ADDHANDLER statement in Sub Main. Any validation errors experienced by the XmlValidatingReader object as it parses the XML representation of the data in the DataSet appears in the Console window by the code in this procedure: Public Sub ValidationEvent(ByVal sender As Object, ByVal args As System.Xml.Schema.ValidationEventArgs) Console.WriteLine(args.Message) End Sub </li> <li>Save, re-build, and then run the program. You receive the following validation error message in the Console window to report the invalid value assigned to the Age column. The error message displays the location of the error as present in the source XML representation of the data in the DataSet:

The 'age' element has an invalid value according to its data type. An error occurred at.

</li></ol>

The limitations of this workaround are that validation errors related to constraints defined as XSD facets can be identified only after the records are added to a DataTable; the error messages to report these errors are XML based as opposed to being DataSet oriented.

To locate the source line in the XML that generated the error, write out and examine the DataSet's XML (use the GetXml and WriteXml DataSet methods).You also have to useXmlValidatingReader to validate the data. This is the only known workaround to address this bug, and it can be used effectively to validate the data before updating a target data source with data that is not valid.

Keywords: kbbug KB811107

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.