为什么s:date类型的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

我正在尝试从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" 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() );