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

2024-02-05

我正在尝试从 WSDL 创建一个新的服务引用,并且我希望所有属性都是 DateTime 而不是字符串。

例如,联系人的 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>

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

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

    [OptionalField]
    private string EmailField;

    private string BirthDateField;
}

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


这些问题中有一些很好的信息:如何在 WCF OperationContract 参数中生成 xs:Date https://stackoverflow.com/questions/776534/how-to-generate-xsdate-in-wcf-operationcontract-parameter and .NET 3.5 中日期时间序列化的最佳实践 https://stackoverflow.com/questions/65164/best-practices-for-datetime-serialization-in-net-framework-3-5-sql-server-2008.

正如 Alex 在对这个问题的评论中指出的那样,WCF 不支持xs:date类型。然而,也许更准确的说法是,默认值DataContractSerializer不支持该类型,而上述问题表明XmlSerializer可以处理它。

看到这个link http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/ for a DataContractSerializer反对XmlSerializer比较。

如果我运行:

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>

这个类是否已生成:

/// <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;
        }
    }
}

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

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

这种方法并非没有缺点。这Service1.cs如果生成的文件没有显着不同/ser:XmlSerializer参数,您将在其中获得其他类,例如WebMethodNameRequest, WebMethodNameRequestBody, WebMethodNameReponse, WebMethodNameReponseBody等等。如果这些类对于您与服务的交互很重要,那么我的方法可能不适合您。

Edit:

就可空属性而言,这个问题有一些很好的信息:svcutil.exe - 生成的代理不允许可空字段 https://stackoverflow.com/questions/1009895/svcutil-exe-proxy-generated-not-allowing-for-nullable-fields

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

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

会生成一个名为public System.Nullable<System.DateTime> SomeProperty在代理类中。

但是,在您的情况下,您可以使用SomePropertySpecifiedproperty 来指示该属性的存在或不存在。当您拥有这些类型的属性时,就会生成minOccurs="0".

在日期格式方面我不确定。xs:date值旨在为 yyyy-mm-dd 以及可选时区信息(w3.org http://www.w3.org/TR/xmlschema-2/#date)。如果 Oracle 期望日期采用不同的格式,那么我想知道它们会如何xs:date根本没有价值观。

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

Edit 2:

我有点不清楚“日期必须采用数据库格式”到底是什么。 Oracle 文档中的意思。如果类型是xs:date那么将它们序列化为数据库格式肯定意味着它不再是一个xs:date?

尽管如此,您在这方面仍然可以尝试一些事情:

  • 强制 XmlSerializer 将 DateTime 序列化为“YYYY-MM-DD hh:mm:ss” https://stackoverflow.com/questions/3534525/force-xmlserializer-to-serialize-datetime-as-yyyy-mm-dd-hhmmss?rq=1
  • http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerialized-Correctly http://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly

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

你确定那些*IsSpecified参数没有吗?要使用我的Contact以上面的类为例,minOccurs=0 on the BirthDate财产会给Contact类一个额外的属性称为BirthDateIsSpecified.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在生成服务引用时,s:date 类型的 XSD 元素会变成字符串? 的相关文章

随机推荐