Zulfiqar's weblog

Architecture, security & random .Net

WCF Behavior Ordering

Posted by zamd on June 2, 2009


WCF behaviours are applied based on a particular evaluation order. Exact details are available here 

The ServiceHost applies behaviors in the following order:

1.     Contract

2.     Operation

3.     Endpoint

  1. Service

Please note within any collection of behaviors, ordering is NOT guaranteed. Because of that sometimes when you configure some aspects of runtime in your custom behavior (for example, TransactionRequired property of the operation) – they get overwritten by default WCF behavior. For example, following will not work and TransactionRequired will always be set to false (default value).

class TestBv : Attribute, IOperationBehavior

{

    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation){}

 

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)

    {

        dispatchOperation.TransactionRequired = true;

    }

 

    public void Validate(OperationDescription operationDescription){}

}

Why? Because here WCF is executing default OperationBehavior after the execution of your custom behavior. Please note, missing OperationBehaviorAttribute doesn’t mean that behavior won’t be applied at all rather it mean a default OperationBehavior will be applied.

So how to fix this?

Use explicit ordering: Remove the bahavior from the collection and apply it at a particular time yourself. Here is the modified behavior which will work correctly.

class TestBv : Attribute, IOperationBehavior

{

    IOperationBehavior orignal;

 

    public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters) { }

    public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation){}

 

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)

    {

        orignal.ApplyDispatchBehavior(operationDescription, dispatchOperation);

        dispatchOperation.TransactionRequired = true;

    }

 

    public void Validate(OperationDescription operationDescription)

    {

        this.orignal = operationDescription.Behaviors.Find<OperationBehaviorAttribute>();

        if (orignal != null)

             operationDescription.Behaviors.Remove(orignal);

    }

}

HTH…

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: