6

我是第一次编写 WCF 服务。该服务及其所有客户端(至少目前是这样)都是用 C# 编写的。该服务必须对其传递的数据进行大量输入验证,因此我需要有一些方法将无效数据指示回客户端。我已经阅读了很多关于故障和异常、将异常包装在故障中的文章,以及许多让我更加困惑的相互冲突的文章。处理这种情况的正确方法是什么?

我应该完全避免异常并打包结果返回消息吗?我应该创建一个特殊的故障,还是一个特殊的异常,或者像我为非 WCF 验证函数那样抛出 ArgumentExceptions?

我现在拥有的代码(受MSDN影响)是:

[DataContract]
public class ValidationFault
{
    [DataMember]
    public Dictionary<string, string> Errors { get; private set; }

    [DataMember]
    public bool Fatal { get; private set; }

    [DataMember]
    public Guid SeriesIdentifier { get; private set; }

    public ValidationFault(Guid id, string argument, string error, bool fatal)
    {
        SeriesIdentifier = id;
        Errors = new Dictionary<string, string> {{argument, error}};
        Fatal = fatal;
    }

    public void AddError(string argument, string error, bool fatal)
    {
        Errors.Add(argument, error);
        Fatal |= fatal;
    }
}

在方法上有 [FaultContract(typeof(ValidationFault))]。那么这是解决这个问题的“正确”方法吗?

4

3 回答 3

4

从 WCF 服务中抛出异常没有用 为什么不呢?因为它作为一个简单的错误回来,你需要

a) 设置故障以包含异常

b) 解析故障以获取异常的文本并查看发生了什么。

所以是的,你需要一个错误而不是一个例外。在您的情况下,我会创建一个自定义故障,其中包含作为故障合同的一部分未能通过验证的字段列表。

请注意,WCF 使用不是 ISerializable 的字典做了一些有趣的事情;它有特殊处理,所以检查返回的消息在网络上看起来不错;如果不是,它会为您返回数组。

于 2008-09-22T12:42:40.487 回答
3

如果您在客户端上进行验证,并且一旦将它们传递给方法(Web 服务调用)就应该具有有效值,那么我会抛出异常。这可能是一个异常,表明参数名称无效。(请参阅:参数异常)

但是您可能不想依赖客户端来正确验证数据,这会让您假设数据可能无效进入 Web 服务。在那种情况下,它并不是真正的例外情况,也不应该是例外。在这种情况下,您可以返回一个枚举或一个 Result 对象,它的 Status 属性设置为一个枚举(OK、Invalid、Incomplete)和一个带有细节的 Message 属性,例如参数的名称。

我会确保在开发过程中发现并修复这些类型的错误。您的 QA 流程应仔细测试客户端的有效和无效使用,并且您不希望将这些技术消息转发回客户端。相反,您想要做的是更新您的验证系统,以防止无效数据进入服务调用。

我对任何 WCF 服务的假设是会有多个 UI。现在一个可能是 Web UI,但稍后我可能会使用 WinForms、WinCE 甚至是不符合您对 .NET 客户端的期望的本机 iPhone/Android 移动应用程序添加另一个。

于 2008-09-18T22:33:44.027 回答
2

您可能想看看 MS Patterns and Practices Enterprise Library Validation 块以及策略注入块链接文本,它允许您使用验证属性装饰数据合同成员并装饰服务实现,以及它的集成对于 WCF,这意味着验证失败会自动返回为 ArgumentValidationException 错误,每个错误都包含每个验证失败的 ValidationDetail 对象。

将 entlib 与 WCf 一起使用,您可以获得大量验证、错误报告,而无需编写太多代码

于 2008-09-22T12:30:52.933 回答