【问题标题】:How to specify if a Field in required in generated Proxy如何指定生成的代理中是否需要字段
【发布时间】:2009-01-18 08:56:57
【问题描述】:

将 DataContract 中的多个元素作为 DataMember 公开的 WCF 服务

[DataMember(IsRequired = true, EmitDefaultValue = false)]
public string Source;

[DataMember(IsRequired = true, EmitDefaultValue = false)]
public string Target;

在客户端生成的代理(通过在VS 2008中添加服务引用)中,客户端可以在Source或Target中传递null或空字符串。如何在客户端强制执行 Source 和 Target。即,如果 Source 或 Target 设置为 null,则客户端应该在调用服务调用之前获得异常。

【问题讨论】:

    标签: c# wcf web-services


    【解决方案1】:

    您无法在客户端强制执行任何操作。想一想,客户端可以由您自定义开发,甚至可能在 .Net 中(如 Java 等)都没有。IsRequired = true 表示该类型必须通过线路序列化该成员,该值可能为 null。

    唯一的方法是在值为 null 时从您的服务器抛出异常并使用正确的故障契约。

    【讨论】:

    • 如果您控制客户端,您绝对可以添加验证以更早地获取错误(即删除往返)。您只是不能(在服务器上)依赖它已经完成。
    • 在 SOA 架构中,我永远不能假设我可以控制客户端。这就是为什么一个明确定义的过错合同是必须的。否则你是正确的。
    【解决方案2】:

    嗯,null (xsi:nil) 和空字符串 都是 值 - 它们不是您想要的值。

    在反序列化期间(在客户端或服务器):

    您可以尝试在 setter 中放入一些代码来为无效值抛出异常?

    或者(对于更复杂的情况),我相信数据合同支持反序列化回调,这应该允许您验证...

    例如,您可以添加(在部分类中,如有必要,在客户端):

    [OnDeserialized]
    internal void OnDeserialized(StreamingContext context)
    {
        if (string.IsNullOrEmpty(Bar))
        {
            throw new InvalidOperationException("No Bar!");
        }
    }
    

    对于预发送检查(在客户端),您必须添加额外的验证方法,或者可能(再次,在部分类中):

    [OnSerializing]
    internal void OnSerializing(StreamingContext context)
    {
        if (string.IsNullOrEmpty(Bar))
        {
            throw new InvalidOperationException("No Bar!");
        }
    }
    

    但是,服务器必须也验证这一点 - 您不能假设发送消息的是 您的客户端代码。

    【讨论】:

    • 那么在什么情况下实际应用了 IsRequired ?如果元素完全来自请求 xml?
    【解决方案3】:

    IsRequired 属性指的是对在线上到达的数据进行的验证。如果您希望在客户端完成验证,则需要在客户端为此添加代码。

    【讨论】:

      【解决方案4】:

      您还可以查看验证应用程序块以及它如何集成到 WCF:

      http://msdn.microsoft.com/en-us/library/cc309334.aspx

      【讨论】:

        猜你喜欢
        • 2013-02-12
        • 1970-01-01
        • 1970-01-01
        • 2018-08-17
        • 2012-11-12
        • 2021-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多