WS Interoperability Tip of the Week. Null dates.


One Web services interoperability issue that I have been investigating recently has to do with using null DateTime values between .NET and Java.  Here’s the problem:


System.DateTime in the CLR is considered a value type, where as the equivalent in Java (java.util.Calendar) is not.  In .NET, value types, including int, double, short etc. cannot be assigned to null.  This applies equally to DateTime:


For example, the following command in C# will not compile.


System.DateTime myDate = null;


(In VB.NET you may think you can do this, but really you can’t <g>)


In Java, java.util.Calendar can be assigned to null – which introduces a couple of problems when you consider passing dates and times over Web Services between the two:


1) How do I send a null DateTime from .NET to Java?
2) What happens if Java sends me a null DateTime?


For #1, this is really up to how you want to handle it (and this is easier to spot as the problem will normally be detected at compile time).  Here are some options:


–  Both the client and the Web service agree a certain date (e.g. 01/01/0001 12:00:00 AM) as a null date. 


–  Make the interface expose a string and pass the date that way instead.  From experience, if you were to do this, I would pass an empty string to indicate a null date. 


–  Create a XSD complexType that contains a DateTime value and pass this instead.  Set the value of this complexType to null to indicate a null date.  (this would be my recommended approach as it get’s you into the habit of passing messages between the two, instead of primitives <g>).


#2 is a little more tricky because if .NET receives a null DateTime from a Java Web Service, it will throw a System.FormatException – which you won’t catch at compile time.  Again, the options above are equally applicable on the Java side.


Which option you choose will depend on your particular situation – and may also be based on whether you are using Web services internally or externally.  


The good news is that we are working on a set of guidance for this and other similar issues.   Catch any my talks, visit the Web services interoperability booth at TechEd or watch this space to find out more…

Comments (10)

  1. Sean says:

    public class Foo

    {

    public Nullable<DateTime> Time { get; set; }

    }

    😉

  2. Sean says:

    *bangs head on desk* Web Service!

    public class Foo : WebService

    {

    [WebMethod]

    [return:XmlElement("Time", DataType="time")]

    public Nullable<DateTime> Time { get; set; }

    }

    will it work?

  3. Sean, according to Don’s post will ASMX for whidbey support Nullable<T>

    For more info: http://www.gotdotnet.com/team/dbox/default.aspx?key=2004-04-21T07:51:45Z

  4. Sean says:

    Good info, thanks.

  5. [ Via C# Items ]WS Interoperability Tip of the Week. Null dates. One&nbsp;Web services interoperability issue that I have been investigating&nbsp;recently&nbsp;has to do with using&nbsp;null DateTime values between .NET and Java.&nbsp; Here’s the problem:System.DateTime&nbsp;in the CLR is considered a value…

  6. Dino Chiesa says:

    I think this is an issue that the developer needs to be aware of, but if s/he follows good practices, there will be no terrible problems.

    Starting from a WSDL that specifies a field in a complexType as xsd:date, the .NET client-side proxy or server-side skeleton that is generated employs the (little-known?) feature in XML Serialization that:

    when you have a value-type property of name Xxxx

    and an additional field of name XxxxSpecified, which is a bool, and is decorated with [XmlIgnore]

    …then, the value of the bool indicates whether the value type is "null" or not.

    In other words, in case #1, you just set XxxSpecified to false, and you will send a "nil" xsd:date to your Java counterpart.

    In case #2, just check XxxSpecified for false before evaluating the value of the property. This works with any value type, including DateTime.

    See http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemXmlSerializationXmlSerializerClassTopic.asp

    for the doc on this (look for the discussion on propertyNameSpecified).

  7. Dino Chiesa says:

    Ahh, I think I have misunderstood the issue.

    If the interface specifies minOccurs=1, then a null date will actually appear in the XML message as something like <Date xsi:nil=’1’/>. This is the thing that causes .NET to choke with a FormatException.

    You can mitigate the problem without changing the server interface or implementation – in other words just by doing some special handling on the client side.

    De-serialize as a string and set a hidden DateTime field behind it. Eg, rather than

    public class MyType {

    public System.DateTime DateTimeField;

    }

    you can do:

    public class MyType{

    private static string formatString= "yyyy-MM-ddTHH:mm:ss.fffffffzzz";

    private static System.Globalization.CultureInfo CInfo= new System.Globalization.CultureInfo("en-US", true);

    [XmlIgnore] public System.DateTime internal_DateTimeField;

    [XmlIgnore] public bool DateTimeFieldIsNull;

    [XmlElement(IsNullable=true)]

    public string DateTimeField {

    set {

    if ((value!=null) && (value != "")) {

    internal_DateTimeField= System.DateTime.ParseExact(value, formatString, CInfo);

    DateTimeFieldIsNull= false;

    }

    else

    DateTimeFieldIsNull= true;

    }

    get {

    return (DateTimeFieldIsNull) ?

    null :

    internal_DateTimeField.ToString(formatString) ;

    }

    }

    }

  8. Actualmente, existem v&#225;rias abordagens que podemos usar para desenvolver servi&#231;os.

    Destacam-se duas:…

  9. Actualmente existem v&#225;rias abordagens que podemos usar para desenvolver servi&#231;os. Destacam-se duas: