Reputation: 6068
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
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
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
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
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