Today we ran into an issue with a Windows Forms application we had written. It was working fine on our development virtual PC’s, but for some reason it failed on the actual host machines that we needed it to run on. The application is written purely against the .NET Framework version 2.0. We do communicate with a service that is using WCF, which is part of the .NET Framework version 3.0, but our client side generated proxy was made using wsdl.exe which should produce a client which can run without having WCF. There are various reasons why we can’t use .NET Framework version 3.0, but I don’t want to go into much detail about that here, except to just say that we can’t use .NET Framework version 3.0, and thus cannot use WCF on the client side.
After some debugging we found out that it is actually the server side service that produces an exception. This is because a field that is optional in the Data Contract sometimes becomes required when other fields have certain values. As we couldn’t enforce this constraint by making the fields required, we had to check it explicitly on the server side. The weird thing was that the objects that were being sent out by the service were fine. They contained the required property. So it had to be modified on the client side, before being sent back to the server. However, we couldn’t find any code that did this in the client. And it was working on our development machines, so why wouldn’t it work on the hosts. Weird stuff.
The problem turned out to be a difference between the original .NET 2.0 framework and the .NET 2.0 SP1 version. We had this service pack installed on our images, but not on our host machines. According to KB925272, Microsoft fixed an issue where when the object is being deserialized the fieldSpecified fields weren’t set properly. These fields were required because in XML you can either not specify the field at all (so there is no XML element in the serialized XML for the field), or make it xsi_nil=“true”. However, in our case, once the objects that were being returned by our service got to the client, the fieldSpecified properties were set to false. Then, when the client decides to sent an object back to the server, the value for all properties that had their corresponding fieldSpecified properties set to false wouldn’t get to the server. This in turned caused our service to generate an exception, because a field that was required didn’t have a value, because it hadn’t been sent by the client.
Obviously, this fix is fine by itself. It’s just too bad that it breaks existing code. So you’ll either have to roll out the Service Pack to all machines, or you’ll have to change your code so that this problem cannot present itself (by explicitly setting all the fieldSpecified properties to true, before sending the objects out). We chose the last solution, because if we’d roll out the service pack on all machines we would have to retest all existing applications, because they might be broken after we install it.