如何配置WCF以支持FaultContracts,其中主机和客户端使用net.pipe在同一进程中?

时间:2008-10-21 00:22:14

标签: wcf unit-testing metadata wcf-binding named-pipes

我正在尝试使用net.pipe绑定为我的客户端交互服务创建进程内单元测试。就像一个好的WCF服务一样,它在服务操作上使用FaultContractAttribute来将可能的错误(包装异常)暴露给元数据。我希望通过XML (App.config)配置客户端和服务端点。但是,每当抛出一个错误时,它只是一个CommunicationException“管道已经关闭”,而不是类型化的故障I期待着。

System.ServiceModel.CommunicationException: There was an error reading from the pipe: The pipe has been ended. (109, 0x6d). 

我尝试为net.pipe添加IMetadataExchange端点,但这不起作用。我也试过了。哪个在Vista上需要我为http端点netsh的ACL。那也行不通。

自定义异常类:

public class ValidationException : ApplicationException { }

这是配置的最新尝试,但它抽出“在服务实施的合同列表中找不到合同名称'IMetadataExchange'”

任何有关如何完成此操作的示例或建议的链接都将不胜感激。

<system.serviceModel>

  <client>
    <endpoint name="Client"
              contract="IService"
              address="net.pipe://localhost/ServiceTest/"
              binding="netNamedPipeBinding"
              bindingConfiguration="netPipeBindingConfig" />
  </client>

  <services>
    <service
      name="Service"
      behaviorConfiguration="ServiceFaults">
      <host>
        <baseAddresses>
          <add baseAddress="net.pipe://localhost/ServiceTest/"/>
          <add baseAddress="http://localhost/ServiceTest/"/>
        </baseAddresses>
      </host>
      <endpoint
        address=""
        binding="netNamedPipeBinding"
        bindingConfiguration="netPipeBindingConfig"

        name="ServicePipe"
        contract="IService" />
      <endpoint
        address="MEX"
        binding="mexNamedPipeBinding"
        bindingConfiguration="mexNetPipeBindingConfig"
        name="MexUserServicePipe"
        contract="IMetadataExchange" />
    </service>
  </services>

  <bindings>
    <netNamedPipeBinding>
      <binding name="netPipeBindingConfig"
               closeTimeout="00:30:00"
               sendTimeout="00:30:00" />
    </netNamedPipeBinding>
    <mexNamedPipeBinding>
      <binding name="mexNetPipeBindingConfig"></binding>
    </mexNamedPipeBinding>
  </bindings>

  <behaviors>
    <serviceBehaviors>
      <behavior name="ServiceFaults">
        <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
      <behavior name="MEX">
        <serviceMetadata 
          httpGetEnabled="true"
          httpGetUrl="http://localhost/ServiceTest/MEX"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>

</system.serviceModel>

4 个答案:

答案 0 :(得分:2)

如果您在上面描述的ValidationException类是您用于出错的类,则可能是您的问题的根源。您应该从FaultException派生故障异常,因为它是Serializable。 ApplicationException不是。

Wagner是对的,您需要使用FaultContract属性来装饰您的操作定义,并为其指定合同类型。您还应该使用DataContract和DataMember属性来修饰FaultContract。

答案 1 :(得分:0)

几天前我也犯了同样的错误 我解决了创建自己的类(MyFault)并从服务器抛出FaultException并在客户端捕获它们的问题。 MyFault有一个字符串成员,它是我想让客户看到的异常消息。

我希望自己清楚明白......我会尝试寻找一个很好的样本,我会在这里发布

答案 2 :(得分:0)

问题很可能是反序列化或序列化请求或响应时出错。启用跟踪并使用svctraceviewer查看日志以确定错误。

另外,请确保您的错误异常标有[DataContract],并且不会继承和非[DataContract]类。

答案 3 :(得分:0)

要补充的最后一件事。您的运营合同是否定义了他们正在使用的ServiceFault?。

我的理解是你必须在操作层定义你正在使用的ServiceFaults,并且你的业务逻辑抛出一个FaulException,其中T是你定义的ServiceFault。