views:

3161

answers:

4

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/"/&gt;
        </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"/&gt;
      </behavior>
    </serviceBehaviors>
  </behaviors>

</system.serviceModel>

A: 

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

sebastian
here! take a look at this... http://msdn.microsoft.com/en-us/library/system.servicemodel.faultexception.aspx
sebastian
yeah, I that's the client is setup. However, the actual exception thrown is a raw CommunicationChannelFault-with no data. What I'm doing server side is I have a custom ValidationException, where Data is filled with errors. That is being wrapped by FaultException<ValidationExceptio>().
Kris
A: 

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.

jezell
A: 

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.

Wagner Silveira
+2  A: 

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.

Joseph DeCarlo