static void

WCF Behavior

Common Tweaks

The maximum message size quota for incoming messages (65536) has been exceeded.- increase maxReceivedMessageSize!

Throttling: maxConcurrentCalls.

InstanceContextMode

PerCall is default (NB: goes on implementation, not interface)

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class Service1 : IService

Sessions

If you use sessions, the contract must state for the client

[ServiceContract(SessionMode = SessionMode.Required)]
public interface IService

And then implement it

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class Service1 : IService

If the client tries to use an open session after it expired, it gets a CommunicationObjectFaultedException. The default is 10 minutes - see ReliableSession.InactivityTimeout and Binding.ReceiveTimeout (you can set "infinite" but IIS will recycle you anyway). basicHttpBinding does not support sessions.

[OperationContract(IsInitiating = false, IsTerminating = true)]
Response Final(int number);

IsInitiating
(Default true)- create a session or use existing.
If set to false, cannot open a session.
IsTerminating
(Default false)- close a session (still need the proxy to Close)

Singleton

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Service1 : IService

It supports clients who uses sessions, but obviously everything must be thread-safe. You can create a self-hosted service passing in the singleton into the constructor.

Instance Behaviors

[OperationBehavior(ReleaseInstanceMode =
    ReleaseInstanceMode.BeforeAndAfterCall)]
public void UpdateResource()

BeforeCall
creates new instance (disposes any existing instance)
AfterCall
disposed when finished
BerforeAndAfterCall
InstanceContextMode.PerCall (for one method while the others have sessions)

Concurrency

You can queue requests with Single concurrency (or Multiple to handle simultaneous calls)

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]
public class Service1 : IService

Reentrant is locked like Single, but can release locks which processing (inner WCF calls)

Duplex messaging

Because it does a callback, these must be ConcurrencyMode = ConcurrencyMode.Multiple or Reentrant (not single).

Transactions

See also contracts where you can specify [TransactionFlow(TransactionFlowOption.Mandatory)]

//requires transaction and will commit when finished
[OperationBehavior(TransactionScopeRequired = true)]
public void DoWork()

MSMQ transactions can't span both ends of the queue, but you can do batch transactions by adding an endpointBehavior with <transactedBatching maxBatchSize="100"/>.
On the service implementation add [ServiceBehavior(ReleaseServiceInstanceOnTransactionComplete = false)] so the instance keeps alive through the batch

Anonymous Behavior

In .Net 4.0+, you don't need a <service> configuration with endpoints at all- it can autogenerate for your contracts and schema (default for http is basicHttpBinding). Change the mappings (http default with <protocolMapping><add scheme="http" binding="wsHttpBinding" bindingConfiguration="MyBindingConfiguration"/>

Unnamed behavior elements (or name="") refer to the current service.

WCF Runtime Extensibility

You add an IEndpointBehavior which implements ApplyClient/ApplyDispatchBahvior or ApplyBindingParameters:
endpoint.Behaviors.Add(myIEndpointBehavior)

public class LoggingEndpointBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint,
    BindingParameterCollection bindingParameters)
    { }
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        //implements IClientMessageInspector
        var inspector = new MessageLogInspector();
        clientRuntime.MessageInspectors.Add(inspector);
    }
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        //implements IDispatchMessageInspector
        var inspector = new MessageLogInspector(); 
        endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector);
    }
    public void Validate(ServiceEndpoint endpoint)
    { }
}

To modify it through a configuration file (in extensions/behaviorExtensions- the name can then be an element under endpointBehaviors/behavior/), derive from BehaviorExtensionElement (CreateBehavior())