Kris
Kris

Reputation: 6068

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. 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.

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.

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"

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>

Upvotes: 4

Views: 5310

Answers (4)

Joseph DeCarlo
Joseph DeCarlo

Reputation: 3278

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.

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.

Upvotes: 2

Wagner Silveira
Wagner Silveira

Reputation: 1626

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

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.

Upvotes: 0

jezell
jezell

Reputation: 2532

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.

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

Upvotes: 0

sebagomez
sebagomez

Reputation: 9619

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.

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

Upvotes: 0

Related Questions