简体   繁体   English

如何使用net.pipe将WCF配置为支持FaultContracts,使主机和客户端处于同一进程中?

[英]How do you configure WCF to support FaultContracts where both the host and client are in the same process using a net.pipe?

I'm trying to create an in-process unit test for my service to client interactions using net.pipe binding. 我正在尝试为使用net.pipe绑定的客户端交互服务创建进程中的单元测试。 Like a good WCF service it uses FaultContractAttribute on service operations to expose possible faults (wrapped exceptions) to metadata. 与良好的WCF服务一样,它在服务操作上使用FaultContractAttribute来向元数据公开可能的错误(包装的异常) I would like to have the client and service endpoints configured thru XML (App.config). 我想通过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. 但是,每当引发故障时,它只是CommunicationException“管道已关闭”,而不是我所期望的类型化Fault。

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. 我尝试为net.pipe添加IMetadataExchange端点,但这没有用。 I also tried . 我也试过了。 Which being on Vista required me to netsh the ACL for the http endpoint. 在Vista上哪个需要我netsh http端点的ACL。 That too did not work. 那也没有用。

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>

If the ValidationException class you describe above is the class you are using for faults, it may be the source of your problem. 如果上面描述的ValidationException类是用于故障的类,则可能是问题的根源。 You should derive your fault exceptions from FaultException because it is Serializable. 您应该从FaultException派生故障异常,因为它是可序列化的。 ApplicationException is not. 不是ApplicationException。

Wagner is right, you need to decorate your operation definition with a FaultContract attribute giving it the type of your contract. Wagner是正确的,您需要使用FaultContract属性装饰您的操作定义,并为其指定合同的类型。 You should also to decorate your FaultContract with DataContract and DataMember attributes as well. 您还应该使用DataContract和DataMember属性来装饰FaultContract。

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)并从服务器抛出FaultException并在客户端捕获它们的问题。 MyFault has a string member wich is the Exception Message I want the client to see. MyFault有一个字符串成员,该字符串成员是我希望客户端看到的异常消息。

I hope I made myself clear... I'll try to look for a nice sample and I'll post it here 希望我能说清楚...我将尝试寻找一个不错的示例,并将其发布在这里

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]类。

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。

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

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