In WCF service, one service can send managed exception information in the detail SOAP faults from service to client using the IncludeExceptionDetailInFaults property. By default its value is false, but you can chage it; in this post I'll show the possible ways to change this value using different techniques.
Using config file
This is the most common way, to do it you must specify in the config file of the WCF service the includeExceptionDetailFaults attribute to true. With this action every endpoint associated to WCF service will send managed exception information.
<system.serviceModel>
<services>
<service name="devdeo.WCF.DebugService"
behaviorConfiguration="DebugServiceConfiguration">
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DebugServiceConfiguration">
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Using code
One way is setting the IncludeExceptionDatailInFaults property to true using the ServiceBehaviorAttribute.
[ServiceContract(Namespace="http://wcf.devdeo.com/debug/")]
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class DebugService
{ }
Also, you can get the behaviors associated to WCF service using the Behaviors property and search the behavior that is related with the ServiceDebugBehavior object and set its property to true.
[ServiceContract(Namespace=http://wcf.devdeo.com/debug/)]
public class DebugService
{ }
using (ServiceHost host = new ServiceHost(typeof(DebugService)))
{
ServiceDescription svcDesc = host.Description.Behaviors;
ServiceDebugBehavior svcDebug = svcDesc.Behaviors.Find<ServiceDebugBehavior>();
svcDebug.IncludeExceptionDetailInFaults = true;
host.Open();
}
Enable the property partially
Supose that you have a WCF service with two endpoint: debubep1 and debugep2 (see below the config file that represent the configuration), now you need that only the endpoint called debugep1 sends managed exception information.
<system.serviceModel>
<services>
<service name="devdeo.WCF.DebugService"
behaviorConfiguration="DebugServiceConfiguration">
<endpoint address="net.tcp://localhost:8009/wcf/debugep1"
binding="netTcpBinding"
bindingName="debugep1"
bindingNamespace="http://wcf.devdeo.com/binding/"
contract="devdeo.WCF.DebugService" />
<endpoint address="net.tcp://localhost:8009/wcf/debugep2"
binding="netTcpBinding"
bindingName="debugep2"
bindingNamespace="http://wcf.devdeo.com/binding/"
contract="devdeo.WCF.DebugService" />
</service>
<behaviors>
<serviceBehaviors>
<behavior name="DebugServiceConfiguration">
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</services>
</system.serviceModel>
To implement this, you must create a custom service class that derives from Attribute class and IServiceBehavior interface. After it, override the ApplyDispatcherBehavior method to evaluate each endpoint reprensted by the ChannelDispatcher class and change the IncludeExceptionDetailInFaults to true.
The ApplyDispatcherBehavior method allows to change run-time property values or insert custom extension objects such as error handlers, message or parameter interceptors, security extensions, and other custom extension objects.
[ServiceContract(Namespace = "http://wcf.devdeo.com/debug/")]
[CustomDebugBehavior]
public class DebugService
{ }
public class CustomDebugBehaviorAttribute : Attribute, IServiceBehavior
{
#region IServiceBehavior Members
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints,
System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
// to-do...
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers)
if (cd.BindingName.Equals("http://wcf.devdeo.com/binding/:debugep1"))
cd.IncludeExceptionDetailInFaults = true;
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
// to-do...
}
#endregion
}
At the end, start the WCF service normally.
using (ServiceHost host = new ServiceHost(typeof(DebugService))) {
host.Open();
...
}
Remember that returning managed exception information to services can be a security risk. This is because exception details expose information about the internal client implementation that could be used by unauthorized services.
NOTE: you can read the spanish version of this post at Propiedad IncludeExceptionDetailInFaults en WCF