.Net Meanderings

Richard Blewett's wanderings around .NET

Please read my disclaimer. Subscribe to my RSS feed

Web Services, Value Types and Nullable

Under .NET 1.x there was always an issue with changing webservices and value types. The problem being that if a the server side added a new value type parameter and the client didn't update, the client wouldn't send the extra information in the soap request. This meant that the web service received the packet and had to decide what to do with the new parameter. The .ASMX infrastructure decided to set the value type to its default value. Now for reference types this is not a problem because the default value for a reference is null. Value types on the other hand do not support a null value and so are zeroed.

Semantically this is fine for some situaltion and disasterous for others:


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Add(int x, int y)
  {
    return x + y;
  }
}
      

is fine if create a new version of Add by adding third param, z.


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Add(int x, int y, int z)
  {
    return x + y + z;
  }
}
      

As adding zero is a no-op. However multiplication is a very different story:


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Multiply(int x, int y)
  {
    return x * y;
  }
}
      

This breaks horribly if we add a z to the parameter list.


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Multiply(int x, int y, int z)
  {
    return x * y * z;
  }
}
      

This version always returns zero. This issue is one of the biggest web service interop problems that .NET faces as Simon Fell points out.

Today I was teaching the web service module of Essential .NET 2 and stumbled upon something I hadn't realised.

As you probably know by now, .NET 2.0 introduces generic types. Now as you can probably imagine generics and web services don't really mix. However one of my students asked me if using a nullable int would have worked in my multiplication example. So we tried is out and it worked! Changing the new implementation of Multiply to:


[WebService(Namespace="http://www.dotnetconsult.co.uk/webservices/calc")]
public class CalcService
{
  [WebMethod]
  public int Multiply(int x, int y, int? z)
  {
    if( z.HasValue )
      return x * y * z.Value;
    else
      return x * y;
  }
}
      

is fine as the nullable int (int?) has no value if it is not passed in the SOAP request. Looking at the wsdl, it turns out that the z parameter is now marked as nillable. So nullable types have been special cased for web services to help resolve the interop issues.

I must try out the List<> class to see if it also works ok.

04/29/2005 8:26 PM | Comments [253] | #.NET #Whidbey

Content © 2003 Richard Blewett | Subscribe to my RSS feed.

Powered by BlogX