WCF故障和异常

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))]。那么这是处理这个问题的“正确”方式吗?

3个回答

4
抛出异常在WCF服务中没有用处。为什么?因为它会以裸故障返回,您需要:
a)设置故障以包括异常
b)解析故障以获取异常的文本并查看发生了什么。
所以是的,您需要一个故障而不是异常。在您的情况下,我会创建一个自定义故障,其中包含作为故障契约的一部分未通过验证的字段列表。
请注意,WCF对字典进行了有趣的处理,这些字典不是ISerializable的;它具有特殊处理,因此请检查回来的消息在线路上看起来是否良好;如果不是,那么您需要使用数组。

3
如果您在客户端上进行验证并且一旦它们被传递到方法中(Web服务调用),应该具有有效值,那么我会抛出异常。可以是指示参数无效的异常,并带有参数名称(请参阅:ArgumentException)。
但是,您可能不想依赖客户端正确验证数据,这样就假定数据可能无效进入Web服务。在这种情况下,这不是真正的异常情况,也不应该是异常。在这种情况下,您可以返回一个枚举或Result对象,其中Status属性设置为枚举(OK,Invalid,Incomplete),Message属性设置为细节,例如参数名称。
我会确保这些错误在开发过程中被找到和修复。您的QA过程应仔细测试客户端的有效和无效使用,而不想将这些技术消息传递回客户端。相反,您想要更新验证系统以防止无效数据传递到服务调用。
我对任何WCF服务的假设是,将会有多个UI。现在可能是Web UI,但稍后我可能会添加另一个使用WinForms、WinCE甚至本机iPhone/Android移动应用程序,它与.NET客户端的预期不符。

2
您可能想要参考MS Patterns和Practices Enterprise Library Validation block,结合策略注入块。它允许您使用验证属性装饰数据契约成员以及服务实现。此外,与WCF的集成意味着验证失败会自动返回ArgumentValidationException故障,每个故障都包含一个ValidationDetail对象。使用entlib和WCF,您可以获得大量验证和错误报告,而无需编写太多代码。请点击链接获取更多信息。

对于任何感兴趣的人,这里是 EntLib 验证块入门指南的链接:http://msdn.microsoft.com/en-us/library/ff953182(v=pandp.50).aspx。 - Crackerjack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接