【问题标题】:How to check if field exists that has isRequired set to true in WCF如何检查是否存在在 WCF 中将 isRequired 设置为 true 的字段
【发布时间】:2012-10-22 19:38:21
【问题描述】:

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

【问题讨论】:

    标签: wcf datamember


    【解决方案1】:

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

    使用基本类型的属性重现此问题的一种不太常见但简单的方法是将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”以及它是否是“最佳途径”我不知道。当然,这取决于您的情况。

    【讨论】:

    • 所以如果我理解正确并且使用类作为方法的参数并且客户端将调用该方法,它会在发送时抛出异常吗?还是我理解EmitDefaultValue 错了?
    • 是的,就是这样。声明:如果您尝试发送(并因此序列化)未设置必需属性且 EmitDefaultValue 为 false 的对象,则 WCF 客户端将引发异常。如果你有一个绕过这个的客户端,那么 service 将在反序列化时抛出异常。
    • 我刚刚测试过,但并不完全正确(无意冒犯)。如果设置为默认值,它将引发异常。如果我用Required=true, EmitDefaultValue=false 标记一个布尔值并且我在客户端显式地将该布尔值设置为false,它仍然会抛出一个异常。这当然是合乎逻辑的。如果没有三重状态,服务将无法知道该属性是否真的设置了。对于值类型,我可以坚持使用Nullable<T>,对于字符串和类,我可以在String.Emptynull 之间做出区分。谢谢强硬,这真的很有帮助。
    • @Silvermind 未采取任何措施。你当然是对的!随意编辑我的答案以反映额外的信息!
    • 感谢大家帮忙解答这个问题。现在我有一个 WCF Web 服务,它引用了另一个包含模型的项目。现在,如果我在模型的属性上指定 isRequired 并且客户端没有发送该属性,则不会发生错误。难道我做错了什么?错误是否仅发生在 NULL 对象上,或者如果它是 String.Empty 或“”也会发生?我正在尝试确定验证字段的最佳途径。
    猜你喜欢
    • 1970-01-01
    • 2013-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2018-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多