Serialization problem with SqlError

G

Guest

Deserializing SqlExceptions on Windows XP (SP2) originating from a Windows
Server 2003 SP1 machine is problemetic. It may generate the following
exception:

Exception: System.Runtime.Serialization.SerializationException
Message: Member name 'System.Data.SqlClient.SqlError server' not found.
Source: System.Runtime.Serialization.Formatters.Soap
at
System.Runtime.Serialization.Formatters.Soap.ReadObjectInfo.Position(String
name)
at
System.Runtime.Serialization.Formatters.Soap.ReadObjectInfo.GetType(String
name)
at
System.Runtime.Serialization.Formatters.Soap.ObjectReader.ParseMember(ParseRecord pr)
at
System.Runtime.Serialization.Formatters.Soap.ObjectReader.Parse(ParseRecord
pr)
at
System.Runtime.Serialization.Formatters.Soap.SoapHandler.EndElement(String
prefix, String name, String urn)
at System.Runtime.Serialization.Formatters.Soap.SoapParser.ParseXml()
at System.Runtime.Serialization.Formatters.Soap.SoapParser.Run()
at
System.Runtime.Serialization.Formatters.Soap.ObjectReader.Deserialize(HeaderHandler handler, ISerParser serParser)
at
System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream
serializationStream, HeaderHandler handler)
at
System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream
serializationStream)

I have found out that this is due to an incompatibility between the
System.Data assemblies on both machines. The following assemblies are
installed on both machines:

* Client: Windows XP SP2, System.Data.dll (v1.1.4322.2032)
* Server: Windows Server 2003 SP1, System.Data.dll (v1.1.4322.2300)

A SqlException that is thrown on the Windows Server 2003 SP1 machine
contains an error collection of type SqlError. Such an error will be
serialized like this:

<a3:SqlError id="ref-18"
xmlns:a3="http://schemas.microsoft.com/clr/ns...ture=neutral, PublicKeyToken=b77a5c561934e089">
<source href="#ref-15"/>
<number>50000</number>
<state>1</state>
<errorClass>16</errorClass>
<server id="ref-19">PC1882</server>
<message id="ref-20">-Message here-</message>
<procedure id="ref-21">-Procedure here-</procedure>
<lineNumber>24</lineNumber>
</a3:SqlError>

If the same exception is thrown on a Windows XP SP2 machine, then the
<server> tag is missing. This may seem strange, because the Server property
does exist in the v1.1.4322.2032 version. I started Lutz Roeder's .NET
reflector and it shows that the Server property is some kind of stub that
always returns an empty string. There isn't a server field in the class and
it cannot be set by the class' constructor. This explains why it is not in
the serialized message.

If you load the Windows Server 2003 SP1 assembly into the .NET Reflector,
then there is a server field and the server can be set in the constructor.
When the SqlError is constructed, then the server is saved into the field and
returned when the Server property is requested. This explains why it is in
the serialized message. It is good to have the server property in there, but
it is annoying that it isn't compatible anymore.

The Windows Server 2003 SP1 machine serializes the SqlError and includes the
server tag. The client deserializes the message and encounters the server tag
and doesn't know what to do with it and generates the exception listed above.
Although I can explain what is happening, I cannot solve it (yet). I am
currently working on a solution for this problem, but for now I can only
explain what is happening. For anyone else out there that is facing the same
problem it might be nice to know what is actually happening.

It worries me, that although the version numbers are the same (only a
difference in buildnumber) causes these kind of problems. I thought the
versioning issues would have been resolved with .NET. I hope someone can
bring up a solution. I really don't like to implement my own
SerializationBinder to solve this issue (that is what I am thinking of right
now). Can someone please respond to this issue?
 
G

Guest

Microsoft provides a hotfix for .NET Framework v1.1 SP1 that solves the issue
of the empty Server property. This empty property is described as a bug, but
from the disassembled code it is obvious that it was simply not implemented
at all. The problem is described in KB884871
(http://support.microsoft.com/kb/884871).

There is a new System.Data assembly available from Microsoft that fixes this
problem. I am quite certain that it will also be capable of dealing with the
server tag in the serialized data. The hotfix is included in the Microsoft
Visual Studio .NET Hotfix Package 3151 that is described in KB887549
(http://support.microsoft.com/kb/887549).

The hotfix contains v1.1.4322.2038 of System.Data.dll and must be applied to
the client PCs. Unfortunately, hotfixes cannot be downloaded directly but
need to be obtained via Microsoft. See
http://support.microsoft.com/default.aspx?scid=fh;[ln];cntactms for more
information to contact Microsoft. Dutch customers can call 020-5001005 to
obtain the hotfix.

I hope this helps...
 
G

Guest

The hotfix solves the problem, but after the installation of the hotfix the
system cannot deserialize the old SqlError types anymore (I already feared
that this would happen). The following exception is thrown when a
SqlException from an old system (no hotfix/Win2K3 SP1 installed) is received:

Exception: System.Runtime.Serialization.SerializationException
Message: Wrong number of Members. Object System.Data.SqlClient.SqlError has
8 members, number of members deserialized is 7.
Source: System.Runtime.Serialization.Formatters.Soap
at
System.Runtime.Serialization.Formatters.Soap.ReadObjectInfo.PopulateObjectMembers()
at
System.Runtime.Serialization.Formatters.Soap.ObjectReader.ParseObjectEnd(ParseRecord pr)
at
System.Runtime.Serialization.Formatters.Soap.ObjectReader.Parse(ParseRecord
pr)
at
System.Runtime.Serialization.Formatters.Soap.SoapHandler.EndElement(String
prefix, String name, String urn)
at System.Runtime.Serialization.Formatters.Soap.SoapParser.ParseXml()
at System.Runtime.Serialization.Formatters.Soap.SoapParser.Run()
at
System.Runtime.Serialization.Formatters.Soap.ObjectReader.Deserialize(HeaderHandler handler, ISerParser serParser)
at
System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream
serializationStream, HeaderHandler handler)
at
System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream
serializationStream)

It is obvious that it is missing the 'server' tag. It would have been nice
that Microsoft would have created a fix that is backwards compatible, but
this is not the case (unfortunately).

This makes using a mixed environment a bit more difficult. To make
everything work you need to do the following:

* Upgrade all Windows Server 2003 servers to SP1.
* Install the hotfix on all Windows 2000/XP machines (after .NET Framework
v1.1 SP1).

This will fix the problem, however I still think that MS needs to rethink
the impact of serialization when creating hotfixes.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top