我是第一次写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))]。那么这是解决这个问题的“正确”方法吗?
答案 0 :(得分:4)
从WCF服务中抛出异常是没有用的为什么不呢?因为它作为一个简单的故障回来了,你需要
a)将故障设置为包含例外
b)解析故障以获取异常文本,看看发生了什么。
所以是的,你需要一个错误而不是一个例外。在您的情况下,我会创建一个自定义错误,其中包含作为错误合同一部分的验证失败的字段列表。
请注意,WCF使用不是ISerializable的词典做有趣的事情;它有特殊的处理方式,所以检查回来的信息看起来很好;如果没有,它会回到你的阵列。
答案 1 :(得分:3)
如果您正在对客户端进行验证,并且一旦将它们传递给方法(Web服务调用),它应该具有有效值,那么我将抛出异常。它可能是一个异常,表明参数的名称与参数无效。 (参见:ArgumentException)
但您可能不希望依赖客户端来正确验证数据,并且假设数据可能无效进入Web服务。在这种情况下,它不是一个真正的例外情况,不应该是一个例外。在这种情况下,您可以返回一个enum或Result对象,其Status属性设置为枚举(OK,Invalid,Incomplete)和Message属性集,其中包含特定内容,如参数名称。
我会确保在开发过程中找到并修复这些错误。您的质量检查流程应仔细测试客户端的有效和无效使用,并且您不希望将这些技术消息转发回客户端。您要做的是更新您的验证系统,以防止无效数据进入服务调用。
我对任何WCF服务的假设是会有多个UI。现在可能是一个Web用户界面,但后来我可能会使用WinForms,WinCE或者甚至是原始iPhone / Android移动应用程序添加另一个,这些应用程序不符合您对.NET客户端的期望。
答案 2 :(得分:2)
您可能需要查看MS模式和实践企业库验证块以及策略注入块link text,它允许您使用验证属性装饰数据协定成员并装饰服务实现这与它与WCF的集成一起,这意味着返回验证失败,因为ArgumentValidationException自动故障,每个包含ValidationDetail对象,每次验证失败。
使用带有WCf的entlib,您可以获得大量验证,错误报告,而无需编写太多代码