Example Code
Imports System.Xml.Serialization
<System.Serializable()> _
<Xml.Serialization.XmlRoot("SampleData")> _
Public Class SampleData
Public Sub New()
mNameList = New List(Of String)
End Sub
Private mNameList As List(Of String)
Public Property NameList() As List(Of String)
Get
Return mNameList
End Get
Set(ByVal value As List(Of String))
mNameList = value
End Set
End Property
<XmlIgnore()> _
Public ReadOnly Property NameListSpecified() As Boolean
Get
If mNameList Is Nothing OrElse mNameList.Count < 1 Then
Return False
Else
Return True
End If
End Get
End Property
Public Overridable Function GetXml() As String
Dim Buffer As New IO.MemoryStream()
Dim XmlStreamer As New XmlSerializer(Me.GetType)
' Serialize object into XML
XmlStreamer.Serialize(Buffer, Me)
' Encode into String variable
Return System.Text.Encoding.UTF8.GetString(Buffer.ToArray())
End Function
End Class
Module Startup
Sub Main()
Dim DataObject As New SampleData()
DataObject.NameList.Add("Name 1")
DataObject.NameList.Add("Name 2")
Try
Console.WriteLine("SampleData as XML:")
Console.WriteLine(DataObject.GetXml())
Catch ex As Exception
Console.Error.WriteLine("The following error occurred:")
Console.Error.WriteLine(ex.Message)
Console.Error.WriteLine()
Console.Error.WriteLine("Error Stack:")
Console.Error.WriteLine(ex.StackTrace)
End Try
End Sub
End Module
Results Pre-KB928365
The following is the output of the sample application above if KB928365 is not installed:
SampleData as XML:
<?xml version="1.0"?>
<SampleData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<NameList>
<string>Name 1</string>
<string>Name 2</string>
</NameList>
</SampleData>
Results Post-KB928365
The following is the output of the sample application if executed on a machine that has KB928365 installed:
SampleData as XML:
The following error occurred:
Unable to generate a temporary class (result=1).
error CS0200: Property or indexer 'XmlSerializationIssueKB928365.SampleData.NameListSpecified' cannot be assigned to -- it is read only
Status as of 07/13/2007
Microsoft has confirmed this is an issue with KB928365. Specifically they have stated the following:
1. Serialization of List<T> fails on Windows 2003 SP2 and Windows XP SP2 after application of Security Patch KB928365.
2. Failure happens only when the project is written in VB.NET. Same code written in C#.NET works.
Microsoft plans to release a hotfix to correct this issue. I will update this posting when that hotfix has been released.
Status as of 07/16/2007
I had the opportunity to discuss this issue with my Microsoft Support contact again today, and we discovered the following:
1. The failure was introduced by KB934529 (which was not widely distributed), but was included as part of KB928365.
2. Changing the NameListSpecified property to writable will workaround the issue.
3. The two items listed in the “Status as of 07/13/2007” section of this article may be incorrect.
I am waiting to hear back as to why this change was made in the .NET 2.0 Framework.
Status as of 07/19/2007
Here is what Microsoft Support had to say about the issue described above:
The reason behind a sudden change in the behavior of serialization / de-serialization was due to a bug identified in the .NET 2.0 version. First let me explain the bug to you. Consider a case where the xxxSpecified property is not marked with [XmlIgnore] and a set method is provided in the code. In that case, the property will look something like this:
Public Property NameListSpecified() As Boolean
Get
‘code
End Get
Set(ByVal value As Boolean)
‘code
End Set
End Property
So, when this particular object is serialized, the value of this property will appear in the Xml. In our case, it will appear like this:
<NameList>
<string>Name 1</string>
<string>Name 2</string>
</NameList>
<NameListSpecified>true</NameListSpecified>
Everything is fine till now. The problem arises during de-serialization.
During de-serialization, the value of this property should be set as well. You might be aware that XmlSerializer creates dynamic assemblies to accomplish the task of serialization/de-serialization. The code generated during the de-serialization process, in certain cases, did not have the set() method for the property. This was the bug. Hence, the Boolean value used to get set to null, when we were expecting a valid value. This bug was present in .NET 2.0 RTM and was fixed in later updates on System.Xml.dll . (available with hot fixes like 934529, 928365). The fix was in case this property is implemented in code, both the get() and set() has to be provided. You cannot mark this as ReadOnly anymore.
I do fully understand that this scenario is not applicable in our case, as we have
I am waiting to hear back what the KB article number will be and when the .NET 2.0 service pack that contains this fix will be released.
Status as of 08/10/2007
Microsoft sent me a private fix to test against my software yesterday (08/09/2007). The fix was an updated copy of the system.xml.dll (Version 2.0.50727.914). I tested the updated dll against our production code and verified it corrected the issue we were seeing. I will update this posting when the official hotfix is released.
Status as of 08/27/2007
Microsoft contacted me and let me know that KB 941349 (
No comments:
Post a Comment