【问题标题】:Creating a WCF webservice with a single standard response object使用单个标准响应对象创建 WCF Web 服务
【发布时间】:2011-11-24 22:50:28
【问题描述】:

有人要求我使用 WCF 实现一个 Web 服务,它将返回一个标准响应对象,指示 Web 服务调用是成功还是失败,如果发生错误消息,则会返回一条错误消息。

在我看来,这不是 WCF 的用途,对吗?

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

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

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

这是正确的方法吗?

为了实现我的目标,即在发生验证错误之类的事情时简单地返回一个响应对象,我一直在尝试作弊并将请求对象设置为在 AfterReceiveRequest() 中为空,以便跳过对请求的处理。

 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 最有可能被使用的方式背道而驰。有没有办法很好地实现我想要的,或者当事情变糟时我必须发送一个异常类型,而当事情成功时我必须发送一个不同的“正常”响应?

【问题讨论】:

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


    【解决方案1】:

    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. 对于所有其他情况,使用操作的返回值返回错误代码(这方面不例外)

    【讨论】:

    • 感谢 kroonwijk!我想我应该将我的问题更改为专门针对使用 IDispatchMessageInspector.AfterReceiveRequest 在反序列化和调用我的操作之前针对模式验证请求 XML 的情况。如果此时发生 XML 验证错误,我如何返回 ReturnValue 类而不是抛出异常?那是我应该做的事情吗?
    猜你喜欢
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多