为什么s:date类型的XSD元素在生成服务引用时会变成字符串?
我正在尝试从WSDL和所有我希望是DateTime而不是string的属性创建一个新的服务引用 例如,此联系人的xsd定义:为什么s:date类型的XSD元素在生成服务引用时会变成字符串?,date,xsd,wsdl,svcutil.exe,service-reference,Date,Xsd,Wsdl,Svcutil.exe,Service Reference,我正在尝试从WSDL和所有我希望是DateTime而不是string的属性创建一个新的服务引用 例如,此联系人的xsd定义: <s:complexType name="Contact"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="Address" type="tns:Address" /> <s:element minOccurs="0" m
<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>
如果我创建了一个web项目并将其添加为web引用而不是服务引用,那么它将正确地成为DateTime。我认为这与wsdl.exe和svcutil.exe在幕后的工作方式有关,但不管怎样,我一直在努力找出如何正确地让Visual Studio识别此属性应该是DateTime。虽然这不是一个真正的解决方案,但我认为它可以作为一种变通方法它又脏又丑,我知道这一点,但它可能比在代码中使用字符串要好
由于您自己的类(如
Address
)得到了正确的处理,您可以围绕Date
类构建一个简单的包装器,将其包含在项目和模式中。该类将只有一个日期属性或一个字段和一个getter。这些问题中有一些很好的信息:和
正如Alex在对问题的评论中所说,WCF不支持xs:date
类型。但是,可以更准确地说,默认的DataContractSerializer
不支持该类型,而上面的问题表明XmlSerializer
可以处理该类型
请参见此,了解与XmlSerializer
比较的DataContractSerializer
如果我跑步:
svcutil http://my_web_site?wsdl /ser:XmlSerializer /d:C:\temp
然后是如下所示的WSDL片段:
<s:complexType name="Contact">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="BirthDate" type="s:date" />
</s:sequence>
</s:complexType>
<s:element minOccurs="0" maxOccurs="1" name="SomeProperty" type="s:date" nillable="true" />
这种方法并非没有缺点。如果在不使用/ser:XmlSerializer
参数的情况下生成Service1.cs
文件,则文件会明显不同,您将从中获得额外的类,如WebMethodNameRequest
,WebMethodNameRequestBody
,WebMethodNameReponseBody
等。如果这些类在您与服务的交互中很重要,那么我的方法可能不适合您
编辑:
关于可为null的属性,在这个问题中有一些很好的信息:
要在生成的代理类中获得可为null的属性,需要在WSDL中设置nillable
字段。比如说:
<s:complexType name="Contact">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="BirthDate" type="s:date" />
</s:sequence>
</s:complexType>
<s:element minOccurs="0" maxOccurs="1" name="SomeProperty" type="s:date" nillable="true" />
将在代理类中生成名为public System.Nullable SomeProperty
的属性
但是,在您的情况下,您可以使用somepropertysspecified
属性来指示该属性的存在或不存在。这些类型的属性是在使用minOccurs=“0”
时生成的
就日期格式而言,我不确定xs:date
值应为yyyy-mm-dd,带有可选时区信息()。如果Oracle希望日期采用不同的格式,那么我想知道它们怎么可能是xs:date
值
关于您尝试使用的服务,您是否可以提供任何文档或其他信息
编辑2:
我有点不清楚“日期必须是数据库格式”在Oracle文档中的确切含义。如果类型是xs:date
,那么将它们序列化为数据库格式肯定意味着它不再是xs:date
尽管如此,在这方面你还是尝试了一些事情:
您可能需要简单地尝试向web服务发送一些查询,看看这个日期业务是如何影响事情的
您确定没有指定的*参数吗?以我上面的Contact
类为例,BirthDate
属性上的minOccurs=0
将为Contact
类提供一个名为BirthDateIsSpecified
的额外属性,尽管我相信nick_w的回答很好地解决了这个问题(我正在奖励他),我将提供我将在特定情况下使用的解决方案,在这种情况下,仅使用XmlSerializer
是不够的。最后,我想我将使用一个扩展,使用自定义格式说明符将DateTime
对象转换为字符串
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() );
你有没有想过?我也有同样的问题。似乎WCF不支持xs:date
类型。我开始悬赏解决这个问题。我无法解决这个问题;标记答案的哪一部分适合您?假设模式(WSDL)无法更改。我对纯客户端解决方案感兴趣。谢谢,这确实会生成一个DateTime
字段。我有点惊讶,它没有为带有minOccurs=“0”
的方法参数生成一个Nullable
。知道如何处理吗?另外,我正在尝试使用Oracle服务,Oracle似乎希望xs:date
参数的格式不同-dd-MMM-yyyy
而不是yyy-MM-dd
。我相信Oracle在这方面是错的,但是有没有办法强制客户机中的日期采用不同的格式?谢谢,关于可空类型-我想我需要以不同的方式调用该服务。因为我使用的是*PortTypeClient
类,它的方法没有将指定为属性作为参数。我正在使用的Oracle服务如下:。表33-1显示“日期必须采用数据库格式”…指定的参数肯定不存在。也许问题在于我调用的存储过程接受简单的类型参数。所以没有任何物体。只需使用简单类型参数(整数、字符串、日期等)的函数即可。
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() );