Quantcast
Channel: Code Inside Blog
Viewing all articles
Browse latest Browse all 358

WCF Global Fault Contracts

$
0
0

If you are still using WCF you might have stumbled upon this problem: WCF allows you to throw certain Faults in your operation, but unfortunatly it is a bit awkward to configure if you want “Global Fault Contracts”. With this solution here it should be pretty easy to get “Global Faults”:

Define the Fault on the Server Side:

Let’s say we want to throw the following fault in all our operations:

[DataContract]
public class FoobarFault
{

}

Register the Fault

The tricky part in WCF is to “configure” WCF that it will populate the fault. You can do this manually via the [FaultContract-Attribute] on each operation, but if you are looking for a global WCF fault configuration, you need to apply it as a contract behavior like this:

[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = true)]publicclassGlobalFaultsAttribute:Attribute,IContractBehavior{// this is a list of our global fault detail classes.staticType[]Faults=newType[]{typeof(FoobarFault),};publicvoidAddBindingParameters(ContractDescriptioncontractDescription,ServiceEndpointendpoint,BindingParameterCollectionbindingParameters){}publicvoidApplyClientBehavior(ContractDescriptioncontractDescription,ServiceEndpointendpoint,ClientRuntimeclientRuntime){}publicvoidApplyDispatchBehavior(ContractDescriptioncontractDescription,ServiceEndpointendpoint,DispatchRuntimedispatchRuntime){}publicvoidValidate(ContractDescriptioncontractDescription,ServiceEndpointendpoint){foreach(OperationDescriptionopincontractDescription.Operations){foreach(TypefaultinFaults){op.Faults.Add(MakeFault(fault));}}}privateFaultDescriptionMakeFault(TypedetailType){stringaction=detailType.Name;DescriptionAttributedescription=(DescriptionAttribute)Attribute.GetCustomAttribute(detailType,typeof(DescriptionAttribute));if(description!=null)action=description.Description;FaultDescriptionfd=newFaultDescription(action);fd.DetailType=detailType;fd.Name=detailType.Name;returnfd;}}

Now we can apply this ContractBehavior in the Service just like this:

[ServiceBehavior(...), GlobalFaults]
public class FoobarService
...

To use our Fault, just throw it as a FaultException:

throw new FaultException<FoobarFault>(new FoobarFault(), "Foobar happend!");

Client Side

On the client side you should now be able to catch this exception just like this:

try{...}catch(Exceptionex){if(exisFaultExceptionfaultException){if(faultException.Action==nameof(FoobarFault)){...}}}

Hope this helps!

(This old topic was still on my “To-blog” list, even if WCF is quite old, maybe someone is looking for something like this)


Viewing all articles
Browse latest Browse all 358

Trending Articles