tags:

views:

1026

answers:

4

For parameters to an OperationContract that represent a date only (no time component or timezone designator), it is desirable to use xs:Date, to avoid any ambiguity or problems with timezone conversion between client and server.

WCF currently only supports xs:DateTime for serializing DateTime parameters.

What is the easiest way to generate an OperationContract with a parameter that will be serialized as xs:Date?

I'm thinking of having a custom .NET Type "public struct DateOnly" or similar, with implicit casting to/from a standard DateTime, that will somehow automatically generate wsdl as xs:Date.

Is this possible, and how would I go about implementing it?

If it is possible, I suspect the solution might involve using XmlSchemaProviderAttribute on the custom type, but any documentation I've found on this attribute seems a bit opaque.

Update

I find it difficult to believe it will increase the probablity of getting a solution, but I'll follow the site's advice and start a bounty.

For clarity's sake, the condition for the bounty is to provide all the information necessary to construct a solution so that a parameter to a WCF OperationContract can be:

  • serialized as ws:Date and described as such in the generated WSDL.

  • is either a System.DateTime value or can be cast implicitly to/from DateTime.

A: 

Unfortunately WCF doesn't support the xs:Date type. You'd have to create your own "DateOnly" struct, like:

<DataContract()> _
public struct DateOnly
   <DataMember()> public Month as Integer
   <DataMember()> public Day as Integer
   <DataMember()> public Year as Integer
end struct
Keith
Yes I thought I'd need to create my own struct, but I want to make it serialize as xs:Date (using custom XML serialization)? So that non-WCF clients that recognize xs:Date don't need yet another custom type.
Joe
I'm not aware of any way to change that except for modifying the XML of the WSDL on the fly. I'm not sure of the performance implications though. This article doesn't completely address your situation but may get you started on how to modify the SOAP message content.http://blogs.msdn.com/kaevans/archive/2008/01/08/modify-message-content-with-wcf.aspx
Keith
A: 

WCF's defaut serializer (DataContractSerializer) does not support it. But XmlSerializer supports it.

1 - Add the [XmlSerializerFormat] attribute to your contract...

[XmlSerializerFormat]
[ServiceContract]
public interface IMyContract
{
   MyType GetData();
}

2 - In the DataContract type, add the [XmlElement(DataType = "date")] to the member.

public class MyType
{
     [XmlElement(DataType = "date")]
     public DateTime BirthDate {get; set;}
}

Hope this helps

Sly
This doesn't help for date parameters to an OperationContract.
Joe
I'm sorry, I did not realize you were talking about simple DateTime parameter. But won't you have the same issue with your complex types if you don't switch to [XmlSerializerFormat]?
Sly
Yes, the same issue exists for DataMembers and for OperationContract parameters. For DataMembers, using XML Serialization is a workaround (even if it does lose some of the benefits of DataContracts). But I'm looking for a solution that works in both cases, pending the fix that Microsoft is considering for "v.Next": https://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=349215
Joe
A: 

Now that this has come to my attention, I have created a new Suggestion in Connect, at Please Fully Support xs:Date for Date-Only Parameters and DataMembers. I rated this with four stars (important).

If anyone reading this feels this is important (or else disagrees), then please use Connect to vote on it or comment on it.

John Saunders
FYI: I rated your Connect suggestion 4 stars as well.
Sly
I certainly think it's important. In your connect suggestion you state that "I know that one can use [XmlSerializationFormat] to cause the XML Serializer to be used instead of the Data Contract Serializer". While this is a workaround for DataContracts, my understanding is that there isn't a way of specifying XML serailization for operation contract parameters. Is this understanding correct? In any case the MS response to the original (closed) Connect suggestion indicates they are considering this for "v.Next" (not sure if this means V4 or the following version).
Joe
I believe it's possible to configure the entire service contract, service, or endpoint to use the xml serializer. Not quite sure how.
John Saunders
+2  A: 

You specified a requirement to have xs:Date as a parameter in the operation. The thing is, there's a formal way to specify such requirements: WSDL. If I were doing this I would use a WSDL First approach. Start with a WSDL that defines the contract you want, including an xs:date in the interface, wherever it is you want it. Then generate the service stub using svcutil.exe. Remember to pass in /serializer:xmlSerializer .

Cheeso