1

我有一个 DataMember(isRequired:=True),该属性称为 FillerInd。现在您如何判断该字段是否为空或不存在?我在网上阅读,如果需要的字段丢失,则必须对 XML 进行一些序列化和反序列化,否则会抛出异常 MissingMethodException。我不知道如何实现这一点,或者这是否是最佳途径。任何能让我走上正确道路的帮助,我都会非常感激。

4

1 回答 1

4

DataMember 属性IsRequired告诉您该属性是否在线路上是必需的:它是否应该出现在消息中。这会导致异常的典型情况是当服务通过添加属性来更新 DataContract 时IsRequired = true,而不通知客户端。客户端将发送不包含该属性的序列化对象,从而引发异常。

使用基本类型的属性重现此问题的一种不太常见但简单的方法是将EmitDefaultValue属性显式设置为 false。如果您这样做,然后尝试使用该 DataContract 的对象调用操作,则可能会引发异常。考虑这个例子:

// Data Contract
[DataContract]
public class Animal
{
    [DataMember(IsRequired = true, EmitDefaultValue = false)]
    public string Name;
}

// IService
[OperationContract]
int GetIdentifier(Animal animal);

// Client operation
int id = client.GetIdentifier(new Animal()); // Causes exception

这将导致SerializationException(进而导致 CommunicationException)并带有以下消息:

类型中的成员名称 ....Animal 无法序列化。此异常通常是由于在不允许使用空值的情况下尝试使用空值引起的。'Name' 成员设置为其默认值(通常为 null 或零)。成员的 EmitDefault 设置为“false”,表示该成员不应被序列化。但是,该成员的 IsRequired 设置为 'true',表示必须对其进行序列化。此冲突无法解决。考虑将“名称”设置为非默认值。或者,您可以将 DataMemberAttribute 特性上的 EmitDefaultValue 属性更改为 true,或将 IsRequired 属性更改为 false。

请注意,如果您绕过此问题客户端(例如,通过为生成的服务引用编辑reference.cs,以便客户端不再需要DataMember),则服务将在反序列化时遇到异常,这将导致错,我相信。


谈到你的具体评论和问题。

您无需执行任何操作来判断该字段是否为空:WCF 框架会为您处理。如果需要,我想您可以挂钩(反)序列化以了解此问题,甚至在处理消息之前检查消息。

正如我所说,这种情况会导致 SerializationExceptions 和 CommunicationExceptions,而不是MissingMethodException

我不知道您是否需要“IsRequired”以及它是否是“最佳途径”。当然,这取决于您的情况。

于 2012-10-22T20:37:32.167 回答