My experience preparing for and gaining the TS Windows Communication Foundation Development 4 certification.

The (~7 year old) WCF stack to my suprise, is much larger than I ever gave it credit for. 70-513 successfully pointed me toward a number of “off the beaten track” topics, so much so, that I actually quite enjoyed preparing for this exam. Lots of emphasis in the exam on topics such as routing, diagnostics, transactions, sessions and discovery.

  • Know how to control service instancing using InstanceContextMode, and the difference between PerSession, PerCall and Single.
  • Know how to set single and multi-threaded modes of operation using ConcurrencyMode, and the differences between Single, Reentrant and Multiple.
  • Use the MaxConcurrentCalls property of the ServiceThrottlingBehavior to set a maximum concurrency ceiling.
  • Create a request-reply and one-way router using the IDuplexSessionRouter.
  • Know that when assembling custom bindings, its elements must be “stacked” in a very specific order. Layers in order include, Transaction Flow, Reliability, Security, Shape Change, Transport Upgrades, Encoding and Transport. WCF binding stack configuratoin sequence is very important. For example, transactionFlow, windowsStreamSecurity, binaryMessageEncoding, and tcpTransport, is a valid stacked configuration.
  • Consume a REST service using the WebChannelFactory.
  • Enable impersonation across all operations using the ServiceAuthorization behaviors’ ImpersonateCallerForAllOperations. Then individual operations using the OperationBehavior and setting its Impersonation attribute to true.
  • Create a WinForm project that hosts a service. Enable the UseSynchronizationContext property of the ServiceBehavior to enable UI thread affinity for the service.
  • Control the amount in bytes that can be received on a channel with MaxReceivedMessageSize.
  • Setup a non-transaction MSMQ queue, and query its dead letter queue localhost/system$DeadLetter.
  • WCF routing supports a variety of filters, such as IMessageFilterTable and XPathMessageFilterTable. Know how to prioritise your filters. You can assign numeric priorities to filters, where the highest priority is signified by the highest number.
  • Distributed transactions require both the TransactionFlow and OperationBehavior(TransactionScope.Required=true) custom attributes to be defined.
  • The identifier of the transaction is available through Transaction.Currrent.TransactionInformation.DistributedIdentifier.
  • Individual fields in the contract can be secured individually by decorating with ProtectionLevel custom attribute.
  • The SessionMode granularity is defined on the actual service contract such as SessionMode=SessionMode.Required.
  • RESTfulness can is “tolerated” with the WebGet and WebInvoke custom attributes. Example, WebInvoke(UriTemplate="/items/id", Method="DELETE")
  • The infamous Forms Authentication is supported with WCF. Enable ASP.NET compatibility mode, set /scripting/web Services/authentication to enabled, and use the basicHttpBinding binding.
  • UdpDiscoveryEndpoint is a standard endpoint that is pre-configured for discovery operations over a UDP multicast binding.
  • UdpAnnouncementEndpoint is a standard endpoint that is pre-configured to send announcement messages over a UDP binding.
  • Caching of client security tokens can be disabled using the EstablishSecurityContext property, for example binding.Security.Message.EstablishSecurityContext. Generally this only applies to the wsHttpBinding and the WS-SecureConversation exchange between the client and the service.
  • Use the serviceSecurityAudit behavior to audit security events during all service operations. See here for snippet.
  • logMalformedMessages is a valid log level useful for logging garbage messages, in addition to logEntireMessage, logMessagesAtServiceLevel and logMessagesAtTransportLevel. See here for snippet.
  • Transactional aware transports such as a transactional MSMQ queue, can acquire performance gains by batching, by using the baked-in transactedBatching endpoint behavior. This way creating a transaction and committing it in every receive operation is avoided. See here for snippet.
  • Discover services using by specifying what services you are looking for, and find termination criteria (how long the search should last) using FindCriteria. See here for snippet.
  • Correlate traces across both client and server using the propagateActivity attribute. Controls if activity is propagated to other endpoints that participate in the message exchange. Trace files generated by multiple endpoints can be combined to observe how a set of traces on one endpoint flowed to a set of traces on another endpoint. See here for snippet.
  • The IParameterInspector provides BeforeCall and AfterCall hooks for inspecting the message before and after. Fantastic spot for validation logic.
  • Secured services can audit security failures by using the messageAuthenticationAuditLevel attribute of the ServiceSecurityAudit behavior.
  • Data Contracts should be modelled as Message Contracts to define security mechanisms that need to apply. For example ProtectionLevel=SignAndEncrypt.
  • The [IExtensibleDataObject](http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iextensibledataobject.aspx) can be used to store data that is external to a data contract. The extra data is stored in an instance of the ExtensionDataObject class and accessed through the ExtensionData property. In a roundtrip operation where data is received, processed, and sent back, the extra data is sent back to the original sender intact. This is useful to store data received from future versions of the contract.
  • Filter diagnostics using messageLogging filters. /system.serviceModel/diagnostics/messageLogging/filters section, for example <add xmlns:addr="http://http://www.w3***/adressing">/addr:Action[text()='http://foo/response']</add>.
  • All performance counters for a WCF service can be enabled by dropping in the <diagnostics performanceCounters="ServiceOnly" /> diagnostics configuration.
  • One useful application of an endpoint behavior, is to invoke task services such as logging and audit services.
  • Use PrinciplePermissionAttribute(SecurityAction=Demand, Role=LawEnforcement) for role based authentication using ASP.NET roles.
  • FaultException is a generic type that supports taking typed instances (e.g. FaultException(order, “Foo message here”)).
  • Create a single service operation that supports multiple formats (POX, JSON, ATOM) by leveraging the Accepts HTTP verb. Create a new operation that returns [Message](http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.aspx), use current [WebOperationContext](http://msdn.microsoft.com/en-us/library/system.servicemodel.web.weboperationcontext.aspx) methods to return data in the required format.
  • Query the callers identity using an HTTP based binding, with ServiceSecurityContext.Current.PrimaryIdentity.Name or OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name.
  • Specify a certificate to use for representing the service using X509CertificateRecipientServiceCredential.SetCertificate.
  • Secure individual message contract members by setting its ProtectionLevel attribute to either Sign or EncryptAndSign.
  • Create a client proxy that supports a callback channel using DuplexClientBase<TChannel>.
  • Configure services in IIS to have friendly URI’s, by defining a /serviceHostingEnvironment/serivceActivations/add element, for example <add relativeAddress="Info.svc" service="Info" />.
  • Trace encrypted and other personally identifible information (PII) contained in messages, such as usernames and passwords by tweaking your machine.config with <machineSettings enableLoggingKnownPii="true" />.
  • Experiment reading an in memory System.ServiceModel.Channels.Message multiple times, by cloning it with CreateBufferedCopy, and using CreateMessage of the MessageBuffer class.
  • OperationBehavior’s are never defined on a contract, always on the actual service implementation.
  • TransactionFlow is defined on the service contract, not the implementation.
  • A client proxy’s state can be controlled in the event of a channel fault, by invoking it’s Abort method. See here for snippet.

Service Security Audit Snippet

<serviceSecurityAudit 
   auditLogLocation="Default/Application/Security"
   messageAuthenticationAuditLevel= None/Success/Failure/SuccessAndFailure"
   serviceAuthorizationAuditLevel="None/Success/Failure/SuccessAndFailure"
   suppressAuditFailure="Boolean"
/>

Diagnostics Configuration Snippet

<system.serviceModel>
  <diagnostics>
    <messageLogging
        logEntireMessage="true"
        logMalformedMessages="false"
        logMessagesAtServiceLevel="true"
        logMessagesAtTransportLevel="false"/>
  </diagnostics>
</system.serviceModel>

Transactional Batching Snippet

<behaviors>
  <endpointBehaviors>
    <behavior name="endpointBehavior">
      <transactedBatching maxBatchSize="10" />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="CalculatorServiceBehavior">
      <serviceMetadata httpGetEnabled="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

Discovery Client Snippet

// Create DiscoveryClient
var discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());

// Create FindCriteria
var findCriteria = new FindCriteria(typeof(IHackingService));
findCriteria.Scopes.Add(new Uri("http://bencode.net/building46/floor0"));
findCriteria.Duration = TimeSpan.FromSeconds(10); 

// Find IHackingService endpoints            
var findResponse = discoveryClient.Find(findCriteria);

Console.WriteLine("Found {0} IHackingService endpoint(s).", findResponse.Endpoints.Count)

Trace Correlation Snippet

<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel" 
        switchValue="Information, ActivityTracing"
        propagateActivity="true">
         <listeners>
           <add name="traceListener" 
             type="System.Diagnostics.XmlWriterTraceListener" 
             initializeData= "c:\log\Traces.svclog" />
         </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>

Fault State Snippet

var proxy = new FooProxy();
try
{
  proxy.ProcessBar("helloworld");
}
catch
{
  if (proxy.State == CommunicationState.Faulted)
    proxy.Abort();
}

Learning Resources

The SDK includes heaps of cool extensibillity samples, such as the CircularTraceListener circular buffer trace listener, using the WCF MOM pack for operational monitoring.

Basic Windows Communication Foundation Technology Samples

Windows Communication Foundation Extensibility Samples

WCF Development Toolkit

SvcUtil.exe

Google Protocol Buffers for .NET

SoapUI

wfetch

TcpTrace

XmlSpy

SvcTraceViewer.exe

SvcConfigEditor.exe