简体   繁体   English

WCF故障和异常

[英]WCF faults and exceptions

I'm writing a WCF service for the first time. 我是第一次写WCF服务。 The service and all of its clients (at least for now) are written in C#. 该服务及其所有客户端(至少目前为止)都是用C#编写的。 The service has to do a lot of input validation on the data it gets passed, so I need to have some way to indicate invalid data back to the client. 该服务必须对传递的数据进行大量的输入验证,因此我需要有一些方法将无效数据指示回客户端。 I've been reading a lot about faults and exceptions, wrapping exceptions in faults, and a lot of conflicting articles that are just confusing me further. 我一直在阅读很多关于错误和异常,包含错误中的异常,以及许多相互矛盾的文章。 What is the proper way to handle this case? 处理这种情况的正确方法是什么?

Should I avoid exceptions altogether and package a Results return message? 我应该完全避免异常并打包结果返回消息吗? Should I create a special Fault, or a special Exception, or just throw ArgumentExceptions like I would for a non-WCF validation function? 我应该创建一个特殊的错误,或一个特殊的异常,或者只是像非WCF验证函数一样抛出ArgumentExceptions?

The code I have right now (influenced by MSDN ) is: 我现在的代码(受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;
    }
}

And on the method there's [FaultContract(typeof(ValidationFault))]. 在方法上有[FaultContract(typeof(ValidationFault))]。 So is this the "right" way to approach this? 这是解决这个问题的“正确”方法吗?

Throwing an exception is not useful from a WCF service Why not? 从WCF服务中抛出异常是没有用的为什么不呢? Because it comes back as a bare fault and you need to 因为它是一个简单的故障,你需要

a) Set the fault to include exceptions a)设置故障以包括异常

b) Parse the fault to get the text of the exception and see what happened. b)解析故障以获取异常文本并查看发生的情况。

So yes you need a fault rather than an exception. 所以是的,你需要一个错误而不是一个例外。 I would, in your case, create a custom fault which contains a list of the fields that failed the validation as part of the fault contract. 在您的情况下,我会创建一个自定义错误,其中包含作为错误合同一部分的验证失败的字段列表。

Note that WCF does fun things with dictionaries, which aren't ISerializable; 请注意,WCF使用字典进行有趣的事情,这些字典不是ISerializable; it has special handling, so check the message coming back looks good over the wire; 它有特殊的处理方式,所以检查回来的信息看起来很好; if not it's back to arrays for you. 如果没有,它会回到你的阵列。

If you are doing validation on the client and should have valid values once they are passed into the method (the web service call) then I would throw an exception. 如果您在客户端上进行验证,并且一旦将它们传递给方法(Web服务调用),它应该具有有效值,那么我将抛出异常。 It could be an exception indicating that a parameters is invalid with the name of the parameter. 它可能是一个异常,表明参数的名称与参数无效。 (see: ArgumentException) (参见:ArgumentException)

But you may not want to rely on the client to properly validate the data and that leaves you with the assumption that data could be invalid coming into the web service. 但是,您可能不希望依赖客户端来正确验证数据,并且假设数据可能无效进入Web服务。 In that case it is not truly an exceptional case and should not be an exception. 在这种情况下,它不是一个真正的例外情况,不应该是一个例外。 In that case you could return an enum or a Result object that has a Status property set to an enum (OK, Invalid, Incomplete) and a Message property set with specifics, like the name of the parameter. 在这种情况下,您可以返回一个枚举或Result对象,其Status属性设置为枚举(OK,Invalid,Incomplete)和Message属性集,其中包含特定内容,如参数名称。

I would ensure that these sorts of errors are found and fixed during development. 我会确保在开发过程中找到并修复这些类型的错误。 Your QA process should carefully test valid and invalid uses of the client and you do not want to relay these technical messages back to the client. 您的质量检查流程应仔细测试客户端的有效和无效使用,并且您不希望将这些技术消息转发回客户端。 What you want to do instead is update your validation system to prevent invalid data from getting to the service call. 您要做的是更新验证系统以防止无效数据进入服务调用。

My assumption for any WCF service is that there will be more than one UI. 我对任何WCF服务的假设是将有多个UI。 One could be a web UI now, but later I may add another using WinForms, WinCE or even a native iPhone/Android mobile application that does not conform to what you expect from .NET clients. 现在可能是一个Web用户界面,但后来我可能会使用WinForms,WinCE甚至是一个本机iPhone / Android移动应用程序添加另一个,这些应用程序不符合您对.NET客户端的期望。

you might want to take a look at the MS Patterns and Practices Enterprise Library Validation block in conjunction with the policy injection block link text it allows you to decorate your data contract members with validation attributes and also decorate the service implementation, this together with its integration with WCF this means that failures in validation are returned as ArgumentValidationException faults automatically each containing a ValidationDetail object for each validation failure. 您可能希望查看MS模式和实践企业库验证块以及策略注入块链接文本,它允许您使用验证属性装饰数据协定成员并装饰服务实现,以及它的集成使用WCF,这意味着返回验证失败,因为ArgumentValidationException自动错误,每个包含每个验证失败的ValidationDetail对象。

Using the entlib with WCf you can get a lot of validation, error reporting without having to write much code 使用带有WCf的entlib,您可以获得大量验证,错误报告,而无需编写太多代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM