Search

Locations of visitors to this page

Categories

On this page

WCF Behavior Ordering

Archive

Blogroll

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 49
This Year: 5
This Month: 0
This Week: 0
Comments: 69

Sign In

 Tuesday, June 02, 2009
Tuesday, June 02, 2009 1:39:43 PM (GMT Standard Time, UTC+00:00) ( WCF )

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...