Pierre Greborio.NET

Talking about .NET world

Nillable value types for web services

Today I was working on a web service that persist a large XML structure sent by an InfoPath form. I found an interesting issue. The XML schema used by InfoPath declares an XML element as following:

<xs:element name="ShippingDate" type="xs:dateTime" nillable="true"/>

That means that the XML stream can be both validated as:

<ShippingDate>2003-12-17T09:30:47-05:00</ShippingDate>

or

<ShippingDate xsi:nil="true" />

The problem rises when you send the second one to the web method. You'll get a SoapException such as "String was not recognized as a valid DateTime." Ough!! Yes, the DateTime is a value type and then cannot be null!

Is there a solution ? I contacted my friend Christian and asked him if he knows about this issue. After a little IM conversation he suggested to implement a SoapExtension that assign default date times value to empty elements. Too much work for a basic problem. When we will have a DateTime nullable (reference type) ?

Posted: Nov 14 2003, 06:40 PM by PierreG | with 5 comment(s)
Filed under:

Comments

Drew Marsh said:

Well to answer the most relevant part of your question first, the only way to support nu|illable types for value types is to have a default value for the value type (e.g. DateTime.MinValue) that represents the tri-state. Then, add logic via script to your InfoPath form to detect that the field was left empty and set the value to DateTime.MinValue before posting.

To answer the question about when we'll have nullable support for value types, Whidbey will supposedly introduce a System.Nullable<T> generic, though it's not in the alpha bits.
# November 14, 2003 1:44 PM

Pierre Greborio said:

If you have a large XML document with many dateTime elements it's unpractical to normalize the XML document before it is sent to the web service. Moreover, if you need to load it back you have to de-normalize. That's a workaround :-)

To have a Nullable<T> generic class will helps in many situations, like mine and making persistent layer.

Thanks.
# November 14, 2003 3:51 PM

Mike Jensen said:

You can also get around this by setting minOccurs=0 in your .NET web service.

This can be done as follows

public bool ShippingDateSpecified;
public DateTime ShippingDate;

When .NET conducts its introspection, the Specified property makes the ShippingDate property optional in the WSDL.
# March 17, 2004 3:06 PM

Aaron Ching said:

I tried the xxx Specified trick and minOccurs does set to zero. However, InfoPath is still setting the field with "Cannot be blank".

Any ideas?
# March 18, 2004 6:32 PM

Pierre Greborio said:

When the schema define the field nillable then InfoPath send something like:

<ShippingDate xsi:nil="true" />

The only workaround I found from InfoPath side is to normalize the dates just before to send the SOAP payload (OnSubmit).
# March 19, 2004 2:56 AM