为什么类型为s:s的XSD元素在生成服务引用时会成为字符串?

Nic*_*ick 4 xsd wsdl date service-reference svcutil.exe

我正在尝试从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>
Run Code Online (Sandbox Code Playgroud)

BirthDate的类型是s:date,但生成的类型(在Reference.cs中)是一个字符串.

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

    [OptionalField]
    private string EmailField;

    private string BirthDateField;
}
Run Code Online (Sandbox Code Playgroud)

如果我创建一个Web项目并将其添加为Web引用而不是服务引用,它将正确成为DateTime.我认为这与wsdl.exe和svcutil.exe在幕后工作的方式有关,但无论如何,我都在试图弄清楚如何正确地让Visual Studio认识到这个属性应该是一个DateTime.

nic*_*k_w 5

这些问题中有一些很好的信息:如何在WCF OperationContract参数中生成xs:Date.NET 3.5中DateTime序列化的最佳实践.

正如Alex在对该问题的评论中所述,WCF不支持xs:date类型.但是,或许更准确地说默认值DataContractSerializer不支持该类型,而上述问题表明它XmlSerializer可以处理它.

请参阅此链接DataContractSerializer进行XmlSerializer比较.

如果我跑:

svcutil http://my_web_site?wsdl /ser:XmlSerializer /d:C:\temp
Run Code Online (Sandbox Code Playgroud)

然后像这样的WSDL片段:

<s:complexType name="Contact">
    <s:sequence>
        <s:element minOccurs="1" maxOccurs="1" name="BirthDate" type="s:date" />
    </s:sequence>
</s:complexType>
Run Code Online (Sandbox Code Playgroud)

这个类是否已生成:

/// <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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

svcutil调用产生两个文件:Service1.csoutput.config.如果我在项目中包含代码文件并将这些system.serviceModel位添加到配置文件(即web.config或app.config)中,我可以正常调用该服务.例如:

Service1SoapClient client = new Service1SoapClient("Service1Soap");
var contact = client.GetContact();
Run Code Online (Sandbox Code Playgroud)

这种方法并非没有缺点.该Service1.cs如果没有生成的文件是明显不同的/ser:XmlSerializer参数,在这里你会得到额外的课程,如WebMethodNameRequest,WebMethodNameRequestBody,WebMethodNameReponse,WebMethodNameReponseBody等.如果这些类在您与服务的交互中很重要,我的方法可能对您不起作用.

编辑:

在可空属性方面,这个问题有一些很好的信息:svcutil.exe - 生成的代理不允许可空字段

要在生成的代理类中获取可为空的属性,nillable需要在WSDL中设置该字段.所以像这样:

<s:element minOccurs="0" maxOccurs="1" name="SomeProperty" type="s:date" nillable="true" />
Run Code Online (Sandbox Code Playgroud)

将生成public System.Nullable<System.DateTime> SomeProperty在代理类中调用的属性.

但是,在您的情况下,您可以使用该SomePropertySpecified属性来指示属性的存在与否.您拥有这些属性minOccurs="0".

在日期格式方面我不确定.xs:date值可以是yyyy-mm-dd,带有可选的时区信息(w3.org).如果Oracle期望采用不同格式的日期,那么我想知道它们是如何成为xs:date价值的.

是否有关于您尝试使用的服务的任何文档或其他信息?

编辑2:

我有点不清楚"日期必须是数据库格式".意味着在Oracle文档中.如果类型是一个xs:date然后将它们序列化为数据库格式肯定意味着它不再是一个xs:date

不过,你在这方面还是有一些尝试:

您可能只需要尝试向Web服务发送一些查询,以了解此日期业务如何影响事物.

你确定那些*IsSpecified参数不存在吗?要使用Contact上面的类作为示例,minOccurs=0BirthDate属性上将为Contact类提供一个名为的额外属性BirthDateIsSpecified.