如何在 WCF DataContract 中序列化可为 null 的 DateTime?
How to serialize nullable DateTime in a WCF DataContract?
我在序列化这个东西时遇到了问题。
namespace Such.Namespace.Wow
{
[DataContract(Namespace = "http://very.namespace.uh")]
public class DogeResponse
{
[DataMember]
public virtual int Foo { get; set; }
[DataMember]
public virtual DateTime? ExpiringDate { get; set; }
}
}
在生成的 WSDL 中:
<xs:complexType name="DogeResponse">
<xs:sequence>
<xs:element minOccurs="0" name="Foo" type="xs:int"/>
<xs:element minOccurs="0" name="ExpiringDate" nillable="true" type="xs:dateTime"/>
</xs:sequence></xs:complexType>
但是 运行 次异常发生并且 returns 作为 XML 故障:
<SerializationException>
<Message>ValueType 'System.DateTime' cannot be null.</Message>
是的,我看到了一个 "similar" 问题,但它是关于较旧的 .NET 中的 ASMX 服务的。
我想知道如何在 .NET 4.5 WCF 服务中做到这一点?
看起来您首先有一个 DateTime(在服务器端和客户端),然后您将 DateTime 修改为可为 null 的 DateTime,但没有更新客户端。
客户端现在仍然需要 DateTime(因此不允许为 null),但服务器发送的是 null。因此例外。
请更新客户端服务参考。
小心解析 XML。
元素不是有效的 null。这被认为是空字符串,因此不会将 table 转换为日期时间。
要使它为 null,它需要具有特殊的 nill=true 属性。
澄清:
如果您有一本书 xml 元素,其中一个子元素是 book:series,您在填写时有多种选择:
完全删除该元素 - 当您希望表明该系列不适用于本书或该书不属于某个系列时,可以这样做。在这种情况下,永远不会调用具有与 book:series 匹配的模板的 xsl 转换(或其他基于事件的处理器)。例如,如果您的 xsl 将 book 元素转换为 table 行 (xhtml:tr),则使用此方法可能会得到错误数量的 table 单元格 (xhtml:td)。
将元素留空 - 这可能表示系列是“”,或者是未知的,或者这本书不是系列的一部分。将调用匹配 book:series 的任何 xsl 转换(或其他基于 evernt 的解析器)。 current() 的值将为“”。使用此方法,您将获得与下一个描述的方法相同数量的 xhtml:td 标签。
使用 xsi:nil="true" - 这表示 book:series 元素为 NULL,而不仅仅是空的。将调用模板匹配 book:series 的 xsl 转换(或其他基于事件的解析器)。 current() 的值将为空(不是空字符串)。此方法与 (2) 的主要区别在于 book:series 的模式类型不需要允许空字符串 ("") 作为有效值。这对于系列元素没有实际意义,但对于模式中定义为枚举类型的语言元素,xsi:nil="true" 允许元素没有数据。另一个例子是小数类型的元素。如果您希望它们为空,您可以合并一个仅允许 "" 和小数的枚举字符串,或者使用可为空的小数。
我在序列化这个东西时遇到了问题。
namespace Such.Namespace.Wow
{
[DataContract(Namespace = "http://very.namespace.uh")]
public class DogeResponse
{
[DataMember]
public virtual int Foo { get; set; }
[DataMember]
public virtual DateTime? ExpiringDate { get; set; }
}
}
在生成的 WSDL 中:
<xs:complexType name="DogeResponse">
<xs:sequence>
<xs:element minOccurs="0" name="Foo" type="xs:int"/>
<xs:element minOccurs="0" name="ExpiringDate" nillable="true" type="xs:dateTime"/>
</xs:sequence></xs:complexType>
但是 运行 次异常发生并且 returns 作为 XML 故障:
<SerializationException>
<Message>ValueType 'System.DateTime' cannot be null.</Message>
是的,我看到了一个 "similar" 问题,但它是关于较旧的 .NET 中的 ASMX 服务的。
我想知道如何在 .NET 4.5 WCF 服务中做到这一点?
看起来您首先有一个 DateTime(在服务器端和客户端),然后您将 DateTime 修改为可为 null 的 DateTime,但没有更新客户端。
客户端现在仍然需要 DateTime(因此不允许为 null),但服务器发送的是 null。因此例外。
请更新客户端服务参考。
小心解析 XML。 元素不是有效的 null。这被认为是空字符串,因此不会将 table 转换为日期时间。 要使它为 null,它需要具有特殊的 nill=true 属性。
澄清: 如果您有一本书 xml 元素,其中一个子元素是 book:series,您在填写时有多种选择:
完全删除该元素 - 当您希望表明该系列不适用于本书或该书不属于某个系列时,可以这样做。在这种情况下,永远不会调用具有与 book:series 匹配的模板的 xsl 转换(或其他基于事件的处理器)。例如,如果您的 xsl 将 book 元素转换为 table 行 (xhtml:tr),则使用此方法可能会得到错误数量的 table 单元格 (xhtml:td)。 将元素留空 - 这可能表示系列是“”,或者是未知的,或者这本书不是系列的一部分。将调用匹配 book:series 的任何 xsl 转换(或其他基于 evernt 的解析器)。 current() 的值将为“”。使用此方法,您将获得与下一个描述的方法相同数量的 xhtml:td 标签。 使用 xsi:nil="true" - 这表示 book:series 元素为 NULL,而不仅仅是空的。将调用模板匹配 book:series 的 xsl 转换(或其他基于事件的解析器)。 current() 的值将为空(不是空字符串)。此方法与 (2) 的主要区别在于 book:series 的模式类型不需要允许空字符串 ("") 作为有效值。这对于系列元素没有实际意义,但对于模式中定义为枚举类型的语言元素,xsi:nil="true" 允许元素没有数据。另一个例子是小数类型的元素。如果您希望它们为空,您可以合并一个仅允许 "" 和小数的枚举字符串,或者使用可为空的小数。