使用单个标准响应对象创建WCF Web服务

时间:2011-09-26 05:56:23

标签: .net wcf web-services error-handling xml-validation

我被要求使用WCF实现一个Web服务,该Web服务将返回一个标准响应对象,该对象指示webservice调用是成功还是失败,如果出现错误消息则返回错误消息。

在我看来,这不是如何使用WCF,这是正确的吗?

我的问题是我正在使用IDispatchMessageInspector.AfterReceiveRequest()在WCF反序列化并调用我的操作之前验证针对XSD的请求。

如果验证失败,我该如何返回标准响应对象? WCF似乎要我在这个场景中抛出一个FaultException,但我希望接口纯粹返回一个包含任何失败信息的标准响应对象。

因此,这意味着您需要定义一个自定义的故障异常,当您收到的请求在反序列化之前未通过验证时可以抛出该异常,以及在请求成功时发送的第二个标准响应。

这是正确的方法吗?

为了实现我的目标,即在发生验证错误之类的情况下简单地返回单个响应对象,我一直试图欺骗并在AfterReceiveRequest()中将请求对象设置为null,以便跳过请求的处理。 / p>

 object IDispatchMessageInspector.AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
        {
            try
            {
                validateMessage(ref request);
            }
            catch (Exception e)
            {
                request = null;
                return new FaultException<string>(e.Message);
            }
            return null;

        }

然后我可以在BeforeSendReply()中创建自己的自定义响应对象。

 void IDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
        {
            if (correlationState != null)
            {
                reply = CreateMyOwnResponse(((FaultException) correlationState));
            }
        }

但我知道这看起来很愚蠢,并且正在努力反对如何最有可能使用WCF。有没有办法很好地实现我想要或做的事情我必须在事情变坏时发送异常类型,并在事情成功时发出不同的“正常”响应?

1 个答案:

答案 0 :(得分:3)

WCF不会限制返回对象或强制您抛出异常来传达错误的条件。这取决于您在架构中对整体规模的需求和协议。

在我的应用程序中,我总是倾向于有一个int类型的返回参数,当发生错误时它会变为负数,并且当操作成功完成时为零。您还可以使用更复杂的返回参数,其中包含错误结构,例如:

[DataContract]
public class ReturnValue
{
  [DataMember]
  public int ReturnCode;

  [DataMember]
  public string ResultingDescription;

  // enum listing severities like Critical, Warning, etc.
  [DataMember]
  public Severity Severity;
}

如果您需要复杂的返回参数作为操作的返回,您可以拥有以下签名:

[OperationContract]
ReturnValue MyOperation (int param1, string param2, out MyOperationResult result);

我的经验法则是:

  1. 只针对意外和未处理的异常(在开发时您没有预料到的事情)在服务边界上抛出异常

  2. 对于所有其他情况,请使用您的操作的返回值返回错误代码(在这方面不是例外)