3

I am consuming a SAP-NetWeaver web-service. The response object contains a data and when it is not set it returns "0000-00-00". This leads to a deserialization error in my .NET 4.0 WCF proxy because the minimum valid date for .NET would be "0001-01-01".

I asked the SAP-developer to decorate the date element with the minoccurs="0" attribute and omit it if there's no value present but he states he can't do so.

Before I ask him to return "0001-01-01" for empty dates - just for my WCF proxy - I would like to know:

  1. Is "0000-00-00" a valid date in terms of SOAP? Couldn't find it in any SOAP specification so please let me know your source of information.

  2. Is there a way to tell the .NET deserializer to accept "0000-00-00" and handle it like DateTime.MinValue?

Many thanks!

UPDATE: Now the SAP-web-service returns an empty element if the date is null. But my problem remains the same.

mono68
  • 2,080
  • 19
  • 27

2 Answers2

1

there's a nice talk on this

here

it is possible to simply implement custom de serialisation of the class. so that the values of "0000-00-00" would be catched and converted into DateTime.MinValue. UPD: this is the code I've been talking about.

[OnDeserializing]
void OnDeserializing(StreamingContext c)
{
  if (MyCustonObj == null)
  {
    MyCustonObj = new MyCustomClass();
    MyCustonObj.MyStrData = "Overridden in  deserializing";
  }
}
Community
  • 1
  • 1
Igarioshka
  • 677
  • 3
  • 14
  • Thank you but if you are pointing at the OnDeserializedAttribute in the accepted answer then I don't think this will work here because as far as I know the deserialization error would occur before the method decorated with the OnDeserializedAttribute would be invoked. – mono68 Feb 06 '12 at 10:32
  • @mono68 there is an OnDeserializingAttribute in the answer as well, I think that's the time to make correction on the deserialising process. the OnDeserializedAttribute as the name implies, is implemented right after the de-serialization. – Igarioshka Feb 06 '12 at 11:20
  • Thanks for the update but I would need an example that is more concrete on how to check the response message in order do determine whether to override the date field with a default value or to let the deserialization just happen. – mono68 Feb 07 '12 at 15:14
  • @mono68 could you tell me how do you add the service reference to the app? – Igarioshka Feb 07 '12 at 18:23
  • @lgarioshka via add service reference. I could use svcutil to generate proxy classes though it would be a quite elaborate task since the service requires basic authentication I would have to download the WSDL by hand. – mono68 Feb 08 '12 at 10:27
  • @mono68 just of curiosity, I've wrote a SOAP service, that puts out random stuff, and a client that gets the responses. But I couldn't generate the error, because the types are written on both sides (client/server) correctly, and can not have a mismatch. that would make a breach of contract. And what is the value of c on the event of `void OnDeserializing(StreamingContext c)` ? I always get a null (as it is ignored in WCF). considering your update, the easyest way is to just make the datetime variable nullable, that should stop generating Exceptions. – Igarioshka Feb 08 '12 at 10:55
  • Where do I add this? I don't get it. My WebService returns 0000-00-00 to a DateTime object. So I guess I need to override what shall be done with the value before its actually made into a DateTime object. But where do I add the code? – Sebastian May 22 '13 at 14:00
  • @Sebastian you add the method within the class that will be deserialized, the one that is marked with the [DataContract] attribute. you then mark the method with the appropriate attribute in your case, I guess it would be [OnDeserializing] so that the serializer would find the method and invoke it after desreialization. – Igarioshka May 23 '13 at 19:12
  • @Igarioshka But the class that is deserialized is the DateTime class of the .Net framework. And this I can't alter I guess. I have no clue how to fix this. Can I force my WCF web service to return/interpret dates as strings? – Sebastian May 31 '13 at 07:23
  • @Sebastian but you do have the DateTime as a part of an object property with the getters and the setters? as a possible solution you can wrap the datetime property with a string as noted [here](http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/bef9a9db-2731-4aa6-bc9e-c8e74d6c0f7a) – Igarioshka May 31 '13 at 07:26
  • @Igarioshka Ok I think I know what you trey to tell me. I build a wrapper class with a DataMember "date" of type DateTime. In the wrapper class I add the method from above. Then I set the output value of the soap method to the "date" member of my instantiated wrapper object? Hope you get what I mean. I'll report back! – Sebastian May 31 '13 at 07:53
  • @Igarioshka Helloo again! To clarify: my soap method takes 4 parameters as input + 15 out variables (something like out string projectNumber...). I build a class with all the return values of the soap calls as Members (with the getters + setters). The compiler now tells me I can't use class members for out parameters. I think I'm totally stuck here. Maybe I should open a separate topic – Sebastian May 31 '13 at 09:06
  • @Sebastian yes, that would be better. that way you could post some code. – Igarioshka May 31 '13 at 09:49
  • @Igarioshka http://stackoverflow.com/questions/16893492/soap-deserialization-of-datetime-object-with-value-0000-00-00-fails – Sebastian Jun 03 '13 at 09:18
0

You can implement a SOAP Extension to alter the SOAP before it's deserialized:

http://msdn.microsoft.com/en-us/library/7w06t139.aspx

Jamie Kitson
  • 3,973
  • 4
  • 37
  • 50