Why is an XSD element of type s: date becoming a string when creating a Service Reference?

I am trying to create a new service link from WSDL and all the properties that I expect to be DateTime instead of a string.

For example, this is the xsd definition for Contact:

<s:complexType name="Contact"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="Address" type="tns:Address" /> <s:element minOccurs="0" maxOccurs="1" name="Email" type="s:string" /> ... <s:element minOccurs="1" maxOccurs="1" name="BirthDate" type="s:date" /> </s:sequence> 

The BirthDate type is s: date, but the generated type (in Reference.cs) is a string.

 internal partial class Contact : object, IExtensibleDataObject, INotifyPropertyChanged { [OptionalField] private MembershipMgmtMediator.Address AddressField; [OptionalField] private string EmailField; private string BirthDateField; } 

If I create a web project and add it as a web link instead of the Service Reference, it becomes DateTime correctly. I assume this is due to the way wsdl.exe and svcutil.exe work behind the scenes, but despite this, I'm trying to figure out how to get Visual Studio to recognize that this property must be a DateTime.

+4
source share
3 answers

There is good information on these issues: How to generate xs: Date in the WCF OperationContract parameter and Best Practices for Serializing DateTime in .NET 3.5 .

As Alex says in a comment on this question, WCF does not support xs:date types. However, it might be more accurate to say that the default DataContractSerializer does not support this type, while the above questions indicate that the XmlSerializer can handle it.

See the link for comparing DataContractSerializer with XmlSerializer .

If I run:

 svcutil http://my_web_site?wsdl /ser:XmlSerializer /d:C:\temp 

Then this fragment of WSDL:

 <s:complexType name="Contact"> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="BirthDate" type="s:date" /> </s:sequence> </s:complexType> 

Is this class generated:

 /// <remarks/> [System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.0.30319.1")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/")] public partial class Contact { private System.DateTime birthDateField; /// <remarks/> [System.Xml.Serialization.XmlElementAttribute(DataType="date", Order=0)] public System.DateTime BirthDate { get { return this.birthDateField; } set { this.birthDateField = value; } } } 

This svcutil call creates two files: Service1.cs and output.config . If I include the code file in the project and add the system.serviceModel bits to the configuration file (i.e. Web.config or app.config), I will then call the service as usual. For instance:

 Service1SoapClient client = new Service1SoapClient("Service1Soap"); var contact = client.GetContact(); 

This approach is not without drawbacks. The Service1.cs file is noticeably different if generated without the /ser:XmlSerializer parameter, where you will get additional classes such as WebMethodNameRequest , WebMethodNameRequestBody , WebMethodNameReponse , WebMethodNameReponseBody and so on. If these classes are important in your interactions with the service, my approach may not work for you.

Edit:

In terms of null-value properties, there is good information in this question: svcutil.exe - A proxy-generated non-permissive field with a null-value

In order to get the nullable property in the generated proxy class, the nillable field must be set to WSDL. So something like this:

 <s:element minOccurs="0" maxOccurs="1" name="SomeProperty" type="s:date" nillable="true" /> 

Will generate a property called public System.Nullable<System.DateTime> SomeProperty in the proxy class.

However, in your case, you can use the SomePropertySpecified property to indicate the presence or absence of the property. These properties are generated if you have minOccurs="0" .

Regarding date formatting, I'm not sure. The xs:date values ​​must be yyyy-mm-dd with additional time zone information ( w3.org ). If Oracle expects dates in a different format, I wonder how they can be xs:date values ​​in general.

Is there any documentation or other information that you can provide regarding the service you are trying to use?

Edit 2:

I don’t quite understand what exactly β€œDates should be in database format”. means in docs oracle. If the type is xs:date , then serializing them into a database format undoubtedly means that it is no longer xs:date ?

However, there are a few things you are trying to do in this regard:

You may need to simply experiment with submitting multiple requests to the web service to see how this business dates affects things.

Are you sure *IsSpecified missing? To use my Contact class above as an example, minOccurs=0 in the BirthDate property BirthDate provide the Contact class with an additional property called BirthDateIsSpecified .

+5
source

Although this is not a real solution, I think it can work as a workaround. It's dirty and ugly, and I know that , but it could be better than having String in your code.

Since your own classes (such as Address ) are handled correctly, you can create a simple wrapper around the Date class that you would include in your project and schema. The class will have only the Date property or field and getter.

0
source

Although I believe that nick_w's answer covers the question pretty well (and I reward him with generosity), I provide a solution that I am going to use in my specific case, where just using XmlSerializer not enough. In the end, I think I'm going to go with an extension that converts DateTime objects to a string using a specialized format specifier.

 public static class SoapUtils { public static string ToOraDate( this DateTime? dt ) { return dt != null ? dt.Value.ToString("dd-MMM-yyyy", CultureInfo.InvariantCulture) : } } // Calling a service someDate = DateTime.Now; service.SomeMethod( someDate.ToOraDate() ); 
0
source

Source: https://habr.com/ru/post/1314273/


All Articles