Webservice - 如何在日期时间元素中传递时区信息

Sim*_*one 5 c# datetime soap wsdl web-services

我得到了一个 wsdl,我必须按照它的规范创建一个 web 服务;我正在使用 Visual Studio 2010。其中还有这种复杂类型的定义:

    <xsd:complexType name="Person">
        <xsd:sequence>
            <xsd:element name="surname" type="xsd:string"/>
            <xsd:element name="name" type="xsd:string"/>
            <xsd:element name="birthDate" nillable="true" type="xsd:dateTime"/>
        </xsd:sequence>
    </xsd:complexType>
Run Code Online (Sandbox Code Playgroud)

使用 VS 我得到了以下 cs(我不记得我是怎么做的,但我遵循了网上的说明):

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.1")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(Namespace="http://XXX/Submitter/")]
    public partial class Person {
        private string surnameField;
        private string nameField;
        private System.Nullable<System.DateTime> birthDateField;

        /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string surname {
            get {
                return this.surnameField;
            }
            set {
                this.surnameField = value;
            }
        }
        /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
        public string name {
            get {
                return this.nameField;
            }
            set {
                this.nameField = value;
            }
        }
        /// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)]
        public System.Nullable<System.DateTime> birthDate {
            get {
                return this.birthDateField;
            }
            set {
                this.birthDateField = value;
            }
        }
Run Code Online (Sandbox Code Playgroud)

一切都是正确的:它编译、运行并给出预期的结果;唯一的问题是,给我 wsdl 的另一方在调用我的 Web 服务时,希望得到生日字段为

2013-02-15T17:28:00+01:00
Run Code Online (Sandbox Code Playgroud)

使用时区信息,而他们收到的结果就像

2015-11-17T18:30:11
Run Code Online (Sandbox Code Playgroud)

没有时区。

我的问题是我有一个DateTime?类型,这是我传递给从类实例化的对象的类型;我应该覆盖序列化还是有另一个最常见的解决方案?谢谢

Mat*_*int 3

不幸的是,XSD 与 .NET 在 SOAP Web 服务中支持的内容之间存在严重不匹配。

.NET 对于此类信息只有两种类型 -DateTimeDateTimeOffset. 从技术上讲,最好xs:datetime映射到DateTimeOffset,但事实并非如此。相反,xs:datetime它被映射到DateTime,并在很大程度上依赖于Kind值的属性来确定它的序列化方式。

  • DateTime.Kindis时DateTimeKind.Unspecified,不传递偏移量信息。

  • DateTime.Kindis 时DateTimeKind.Utc,thenZ被传递,与 相同+00:00

  • DateTime.Kindis 时DateTimeKind.Local,则传递与给定日期对应的本地偏移量。

您可以使用 来应用类型DateTime.SpecifyKind,或者如果您想在过程中转换值,可以使用.ToUniversalTime().ToLocalTime()。或者,如果您知道这些值属于特定时区,则可以使用对象的转换方法TimeZoneInfo。只要生成的类型不是任何其他类型,Unspecified它就会包含偏移量。

不幸的是,没有选项可以指定任意偏移量。这将需要该DateTimeOffset类型,而 SOAP 服务不支持该类型。

另外,请考虑该xs:datetime类型对于出生日期来说确实是错误的类型。它应该使用xs:date,这只是一个日期,例如"2013-02-15"。目前 .NET 中还没有支持此功能的类型,尽管即将推出一种类型,例如corefxlabDate包中的 System.Time 包。这对于像这样的场景很有用,但我们是否可以返回并修复 SOAP 序列化器以使用它们还有待观察。

实际上,最好的想法是不要使用 XML 和 SOAP。相反,围绕 JSON 和 REST 设计您的 Web 服务。在那里你可以完全控制这样的事情。