Home > general > Exposing Nullable fields to .NET 1.1 Web Service Clients

Exposing Nullable fields to .NET 1.1 Web Service Clients

I recently ran into an interesting problem exposing a set of WCF services to .NET 1.1 web service clients. I was able to correctly generate the web service proxy class using the 1.1 version of the wsdl.exe utility. However at runtime, I ran into Xml serialization errors when I tried to access my WCF service from a .NET 1.1 web service client.

The problem was that the service method was returning an object that contain several nullable properties (System.Nullable<>). Specifically, they were nullable DateTime fields that were defined similar to this in my .NET 3.0 source:

private System.DateTime? _myTimestamp;
[DataMember]
public System.DateTime? MyTimestamp
{
    get { return this._myTimestamp; }
    set { this._myTimestamp= value; }
}

In a .NET 3.0 web service client, this isn’t a problem since the wsdl.exe utility generates the web service proxy class using System.Nullable<>. But this is a problem with .NET 1.1 clients since nullable types are not supported in .NET 1.1. The generated proxy class actually included two fields:

public DateTime MyTimestamp;
public bool MyTimestampSpecified;

The second xxxxSpecified field is generated when there is the possibility that the value for the field may not be transmitted. The xxxSpecified field is normally set to true, but it should be set to false for one of these nullable fields when it contains null. So the generated proxy class at least looks like it should support the concept of nullable fields. But it chokes when it actually tries to handle a DateTime that doesn’t contain a real value (a System.Nullable<> field without a real value in the .NET 3.0 world).

Although I searched for a solution to this problem, I didn’t find a direct answer. I finally stumbled upon the EmitDefaultValue property of the DataMember attribute. By default, EmitDefaultValue is true, meaning that even if a field contains the default value for that data type, it is transmitted. This means that an Int32 will transmit a value of zero (it’s default value) and so on. My System.Nullable<DateTime> field had a default value of null so null was transmitted. By setting EmitDefaultValue to false for my nullable fields, my problems were solved. My DateTime property now looks like this:

[DataMember(EmitDefaultValue = false)]
public System.DateTime? MyTimestamp
{
    get { return this._myTimestamp; }
    set { this._myTimestamp= value; }
}

Now when this field has a default value of null, it is not emitted to the caller. However, the MyTimestampSpecified field is correctly set to false in this case, indicating that the underlying field doesn’t contain a real value. All is good again and I can access my WCF services from .NET 1.1 and 3.0 web service clients.

I don’t know if this is the best approach to this problem, but so far, it does seem to work for me.

Advertisements
Categories: general
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: