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

时间:2021-08-05 16:50:58

I'm trying to create an in-process unit test for my service to client interactions using net.pipe binding. Like a good WCF service it uses FaultContractAttribute on service operations to expose possible faults (wrapped exceptions) to metadata. I would like to have the client and service endpoints configured thru XML (App.config). However, whenever a fault is thrown, it's just a CommunicationException "pipe has closed", and not the typed Fault I was expecting.

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

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

I tried Adding IMetadataExchange endpoint for net.pipe, but that didn't work. I also tried . Which being on Vista required me to netsh the ACL for the http endpoint. That too did not work.

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

The custom exception class:

自定义异常类:

public class ValidationException : ApplicationException { }

This is the latest attempt at a config, but it pumps out "The contract name 'IMetadataExchange' could not be found in the list of contracts implemented by the service"

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

Any Links to examples or recommendations for how to get this done would be appreciated.

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

<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 个解决方案

#1


2  

If the ValidationException class you describe above is the class you are using for faults, it may be the source of your problem. You should derive your fault exceptions from FaultException because it is Serializable. ApplicationException is not.

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

Wagner is right, you need to decorate your operation definition with a FaultContract attribute giving it the type of your contract. You should also to decorate your FaultContract with DataContract and DataMember attributes as well.

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

#2


0  

I got that same error a few days ago.
I solved creating my own class (MyFault) and throwing FaultException from the server and catching those in the client. MyFault has a string member wich is the Exception Message I want the client to see.

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

I hope I made myself clear... I'll try to look for a nice sample and I'll post it here

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

#3


0  

The problem is most likely an error deserializing or serializing the request or response. Enable trace and view the log with svctraceviewer for the exact error.

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

Also, make sure your fault exception is marked with [DataContract] and does not inherit and non [DataContract] classes.

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

#4


0  

One last thing to add. Do your operation contracts define the ServiceFault they are using?.

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

My understanding is that you have to define which ServiceFaults your're using at the operation layer, and your business logic throw a FaulException where T is the ServiceFault you defined.

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

#1


2  

If the ValidationException class you describe above is the class you are using for faults, it may be the source of your problem. You should derive your fault exceptions from FaultException because it is Serializable. ApplicationException is not.

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

Wagner is right, you need to decorate your operation definition with a FaultContract attribute giving it the type of your contract. You should also to decorate your FaultContract with DataContract and DataMember attributes as well.

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

#2


0  

I got that same error a few days ago.
I solved creating my own class (MyFault) and throwing FaultException from the server and catching those in the client. MyFault has a string member wich is the Exception Message I want the client to see.

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

I hope I made myself clear... I'll try to look for a nice sample and I'll post it here

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

#3


0  

The problem is most likely an error deserializing or serializing the request or response. Enable trace and view the log with svctraceviewer for the exact error.

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

Also, make sure your fault exception is marked with [DataContract] and does not inherit and non [DataContract] classes.

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

#4


0  

One last thing to add. Do your operation contracts define the ServiceFault they are using?.

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

My understanding is that you have to define which ServiceFaults your're using at the operation layer, and your business logic throw a FaulException where T is the ServiceFault you defined.

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