Get Started with BPEL

Build next-generation SOA applications with the leader in BPEL technologies

[Download BPEL tooling & server software today

BPEL consulting and training. BPEL design tools, servers and source code for Eclipse, Apache Tomcat, JBoss, WebSphere, WebLogic, BizTalk and Microsoft .NET.

act/VeBPEL Vendpoints

Copyright 2006 Active Endpoints, Inc. All Rights Reserved. All product names are trademarks or service marks of their respective companies.








Meet the next-generation platform for distributed and edge computing- the only one that is completely platform independent.


Your apps may be visionary, but they're dependent upon enterprise connectivity and distribution. When choosing a development platform, you need a solution that works everywhere- even where connectivity is limited. Voyager Edge™ is a proven, next-generation platform that uses intelligent mobile agent technology to solve mobility and performance issues in highly distributed environments. Faster than RMI, more reliable than client-server systems. Voyager agents can create ad-hoc networks that continue to work when they can't access the enterprise.

Voyager Edge gives architects maximum flexibility to freely develop dynamic, intelligent and decentralized applications in .NET and Java, on the devices and servers they need to target. These applications can run on centralized and edge devices, moving from one device to another while processing the same application. This unifying, next-generation platform can be used to gather, filter, analyze and distribute knowledge rapidly over today's increasingly heterogeneous wired and wireless networks.

Visit Recursion Software at to make your vision a reality.

Download a free trial or intelligent mobile agent white paper at

Call 800.727.8674 to speak with an engineer.






dotnetboard Editor-in-Chief Patrick Hynds [email protected]

Group Publisher Jeremy Geelan [email protected] Mobility Editor Jon Box [email protected] Contributing Editor Derek Ferguson [email protected]

Open Source Editor Dennis Hayes [email protected] Product Review Editor Doug Holland [email protected] VB Editor Keith Franklin [email protected] Smart Client Editor Tim Huckaby [email protected] BizTalk Editor Brian Loesgen [email protected]

Security Editor Duane Laflotte [email protected]


[email protected] Derek Ferguson [email protected] Jeremy Geelan [email protected] Thom Robbins [email protected] John Gomez [email protected] Scott Hanselman [email protected] Dean Guida [email protected] John Sharp [email protected] Jacob Cynamon [email protected] Chris Mayo [email protected] Gary Cornell [email protected] Joe Stagner [email protected] Peter DeBetta [email protected]

Executive Editor Nancy Valentine [email protected]


For subscriptions and requests for bulk orders, please send your letters to Subscription Department Subscription Hotline: [email protected] Cover Price: $6.99/issue Domestic: $69.99/yr. (12 issues) Canada/Mexico: $99.99/yr. Overseas: $129.99/yr. (u.s. banks or money orders). Back issues: $12/ea., plus shipping and handling.


SYS-CON Media 577 Chestnut Ridge Rd., Woodcliff Lake, NJ 07677 Telephone: 201 802-3000 Fax: 201 782-9601 .NET Developer's Journal (ISSN#1541-2849) is published monthly (12 times a year) for $69.99 by SYS-CON Publications, Inc., 577 Chestnut Ridge Road, Woodcliff Lake, NJ 07677. Postmaster: Send address changes to: .NET Developer's Journal, SYS-CON Publications, Inc., 577 Chestnut Ridge Road Woodcliff Lake, NJ 07677.

Copyright © 2007 by SYS-CON Publications, Inc. All rights reserved. No part of this publication may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopy or any information storage and retrieval system, without written permission. For promotional reprints, contact Reprint Coordinator Megan Mussa, [email protected]. Worldwide Newsstand Distribution Curtis Circulation Company, New Milford, NJ Newsstand Distribution Consultant: Gregory Associates / W.R.D.S. 732 607-9941 - [email protected] For list rental information: Kevin Collopy: 845 731-2684, [email protected]; Frank Cipolla: 845 731-3832, [email protected] All brand and product names used on these pages are trade names, service marks, or trademarks of their respective companies. SYS-CON Publications, Inc., is not affiliated with the companies or products covered in .NET Developer's Journal. .NET and .NET-based maiks are trademarks or registered trademarks of Microsoft Corporation in the United States and other countries.

SYS-CON Publications, Inc., reserves the right to revise, republish and authorize its readers to use the articles submitted for publication.

m|a farsYS-coN

WCF Everywhere

By Patrick Hynds

When Microsoft announced the technology that is now known as WCF, there was a lot of expectation and some skepticism. Expectation because it sounded great and would help us solve so many problems and realize so many things that were then very hard to make happen. Skepticism because it sounded great and would help us solve so many problems and realize so many things that were then very hard to make happen...

It turns out that we are somewhere in the middle. The technology has arrived as evidenced by our issue this month, with in-depth how-to articles such as "Creating Custom WCF Behaviors" by Rob Daigneau. The problem is that the tools are lagging. When Web services hit the scene, they were a firestorm of success for two very important reasons. First they solved a problem that needed solving and that everyone understood. In this case WCF also hits the mark, though less forcefully, since we do still have Web services, just not as feature rich as WCF. The second thing that made Web services such a superstar technology is that the tools for making the simple cases work were brain-dead simple: you ran a wizard and got a functional, usable Web service. You could then customize and add and whatever, but it worked for hello world and it let you get a proof of concept done in nothing flat. This is the big weakness we are currently seeing with WCF at the moment. Tools are lacking, and simple things take a lot of steps to make happen. I remember people scoffing at IBM's first Web services that tried to compete with the .NET Web services. The thing that beat down IBM was that it took a dozen or more steps to make a simple example work. WCF isn't that far gone, but complexity does rise very quickly.

Don't get me wrong. I think WCF is a huge enabler. It has made products like CardSpace easier to implement, but I just hope that the tools follow that actually bring this cool and powerful technology to the masses of developers who don't have the time to dig in the guts for weeks just to make practical use of it.®

About the Author...

Patrick Hynds is the Microsoft Regional Director for Boston, the president of CriticalSites, and has been recognized as a leader in the technology field. An expert on Microsoft technology (with, at last count, 55 Microsoft certifications) and experienced with other technologies as well, he previously taught freelance software development and network architecture. Prior to joining Critical-Sites, Patrick was a successful contractor who enjoyed mastering difficult troubleshooting assignments. A graduate of West Point and a Gulf War veteran, he brings an uncommon level of dedication to his leadership role at CriticalSites.

[email protected]


President and CEO Fuat Kircaali [email protected] Group Publisher Jeremy Geelan [email protected]


Senior Vice President, Sales and Marketing Carmen Gonzalez [email protected] Vice President, Sales and Marketing Miles Silverman [email protected]

Advertising Sales Director Megan Mussa [email protected]

Associate Sales Manager Corinna Melcon [email protected]

Events Manager Lauren Orsi [email protected] Events Associate Sharmonique Shade [email protected]


Lead Designer Abraham Addo [email protected] Art Director Alex Botero [email protected] Associate Art Directors Louis F. Cuffari [email protected] Assistant Art Director


Information Systems Consultant Robert Diamond [email protected] Web Designers Stephen Kilmurray [email protected] Richard Walter [email protected]


Financial Analyst Joan LaRose [email protected]

Accounts Payable Betty White [email protected]


201 802-3012 888 303-5282 [email protected]


Circulation Service Coordinator Edna Earle Russell [email protected] Alicia Nolan [email protected]

fSrSYS-CON Top 10 .NET Books

MCAD/MCSD Training Guide (70-320): Developing XML Web Services and Server Components with Visual C# .NET and the .NET Framework Kalani Amit

MCAD/MCSD Training Guide (70-315): Developing and Implementing Web

Applications with Visual C# and Visual Studio.NET Kalani, Amit

MC40 MC&Li HE?




MCAD/MCSD Self-Paced Training Kit: Developing Windows-Based Applications with Microsoft Visual Basic.NET and Microsoft Visual C#.NET, Second Edition Stoecker, Matthew A.

Microsoft .NET XML Web

Services Step by I Step

Freeman, Adam

Enterprise Solution Patterns Using Microsoft .NET: Version 2.0 : Patterns & Practices Microsoft Corporation


Self-Paced Training Kit: Developing Web

Applications with Microsoft

Visual Basic .NET and Microsoft Visual C# .NET, Second Edition Webb, Jeff

Programming Microsoft Windows CE .NET, Third Edition Boling, Douglas

Programming Microsoft Visual Basic .NET Version 2003 (Book & CD-ROM)

Balena, Francesco

Test-Driven Development in Microsoft .NET (Microsoft Professional) Newkirk, James W.

Programming Microsoft Windows CE .NET, Third Edition Boling, Douglas

MCAD/MCSD Self-Paced Training Kit: Microsoft .NET Core Requirements, Exams 70-305, 70-315, 70-306, 70-316, 70-310, 70-320, and 70-300 box vol. set Microsoft Corporation






Population demographics analysis application

Intelligent City Transport System Bpel

Webbasedproperty management system

Build Geography Into Your Applications m-mm ijäg&iy p '


Give Your Users the Complete Picture to Help Them Make Better, Faster Decisions.

Applications that incorporate geographic information system (GIS) technology give users a visual way to analyze their data and make more informed decisions. With ESRI* developer solutions, you can quickly and cost-effectively bring geography and mapping capabilities into your applications, regardless of whether you are building desktop, client/server, mobile, orWeb applications.

ESRI developer solutions enable you to

► Quickly and cost-effectively integrate GIS capabilities into your new and existing applications.

► Select the developer tools that fit best with your architecture (ESRI's developer products encompass GIS components, servers, and Web services).

► Use the development environment of your choice, including Java™, .NET, COM, and C++, and deploy applications on a variety of platforms.

► Access and manipulate data in multiple formats.

Using GIS components within a commerciallDE

Population demographics analysis application

To learn more about the ESRI developer solutions that are right for you, visit

1-888-288-1277 [email protected]

Copyright © 2004 ESRI. All rights reserved. The ESRI globe logo, ESRI,, and are trademarks, registered trademarks, c Other companies and products mentioned herein are trademarks or registered trademarks of their respectivetrademark owne iserviceimarksiofiESRIiinitheiUnitediStates,itheiEuropeaniCommunity,ioricertainiotherijurisdictions.i .iPhotoicourtesyiofiTransportiManagementiCentre,iRoadsiandiTrafficiAuthorityiNSW.

Creating Custom WCF Behaviors

Apply cross-cutting logic to your services

By Rob Daigneau

About the Author

Rob Daigneau has over 18 years of experience designing and implementing enterprise-class applications for a broad array of industries from manufacturing, to financial services, to retail. Rob is currently the Director of Architecture for, one of the most visited web sites in the world. He is also a frequent speaker at conferences such as VS Live! and DevTeach, and writes on a number of industry-related topics at www. DesignPatternsFor.Net .

[email protected]

"W » "Then building WCF services you'll eventu-\l\l ally need to integrate common logic

W V that may be applied across a number of services, contracts, endpoints, or operations. Examples include logging, security, error handling, and message or parameter manipulation. Since this kind of logic cuts across all of these concerns and must often be executed somewhere between the submission of a message from a client to the service, we are presented with an interesting design and programming challenge. Fortunately, WCF provides a feature called Custom Behaviors that lets us inject common and "cross-cutting" logic into the WCF runtime either at the proxy (i.e., the client) or dispatcher (i.e., the service) to achieve such ends.

The WCF Architecture for Extensibility

The WCF architecture is amazingly extensible. Figure 1 provides an overview that we can use to orient ourselves before delving into how the WCF runtime can be extended.

I'll assume that you're familiar with how to write WCF services and consume them from the client, so I won't address the client or service code. The channel stacks are where messages are prepared for transmission across the selected transport on both the client and service sides; this is the layer where your WCF bindings are applied. The middle layer in Figure 1 may be referred to as the Service Model Layer. It's responsible for sending and receiving messages to or from the channels, and invoking the appropriate methods in the client and service side code. This is where custom behaviors can be injected, and is the layer that I'll focus on in this article.

When working with custom behaviors you'll have to become familiar with a set of interface classes in two namespaces. The System.Model. Dispatcher namespace provides interfaces that you can implement on your own custom classes to write "interception logic"; these are the classes where you'll code your common logic. I refer to these as being interceptors because when they're loaded they'll intercept the normal flow of execu

tion on either the proxy or dispatcher side to invoke your custom logic at pre-designated times. Figure 2 illustrates the sequence in which classes that implement these interfaces will be called on in the proxy and dispatcher pipelines, and Table 1 lists a few sample scenarios where you might want to use these interfaces.

The second namespace you'll need to become aware of is System.ServiceModel.Description. This namespace includes interfaces that, when

of the hierarchy in Figure 3, provides access to this tree and is constructed at runtime on the dispatcher side. The same structure is available on the proxy side; the key difference is that the tree created there starts with the ServiceEndpoint class.

In Figure 3 you can infer that the interceptors (see Table 1) loaded by behaviors are applicable across several scopes. If, for example, we add a class that implements IServiceBehavior at the Ser-viceDescription level then the interceptors added via that behavior might apply to the service and all of its endpoints, contracts, and operations. If we add an IEndpointBehavior to a ServiceEndpoint then the interception logic injected by that behavior could apply not only to the endpoint, but also to its contracts and their operations. When IContract-Behaviors are added to a ContractDescription then interception may occur for that contract and its operations. Finally, individual operations can be targeted for interception when IOperationBehav-iors are added at the OperationDescription level.

One generally has three options to choose from when considering how to add behaviors to the description tree. You may add these behaviors pro-grammatically before executing ServiceHost.Open or ChannelFactory.Open, you may use attributes, or you may opt to use configuration files. This article focuses on the last two approaches. Table 2 summarizes how classes that implement these interfaces can be added to the description tree, and it also shows where these interfaces can be applied.

If you choose to use attributes or configuration files to add behavior classes to the description tree, then the WCF runtime will detect these directives just before the ServiceHost or ChannelFactory is actually opened, and will load the corresponding classes into either the dispatcher or proxy trees respectively.

At this point you may be wondering when you should choose to add a behavior through configu-

Interface Name

Sample Use-Case Scenarios


Modify, capture, or inspect message parameters

IClientMessageFormatter, IDispatchMessageFormatter

Custom serialization and deserialization

IClientMessageInspector, IDispatchMessageInspector

Modify, capture, or inspect messages


Select an alternate operation to invoke given a message's content


Access and manipulate native platform data before or after the service operation is invoked

Table 1

implemented on your custom classes, assist in the loading of interceptors into various collections so their logic can be executed as part of the WCF runtime. Classes that implement these interfaces must be added into Behaviors collections prior to opening either the ServiceHost on the service side or the ChannelFactory on the client side. These collections are found in an in-memory representation of the entire service known as the Description Tree. The ServiceDescription class, pictured as the root

Table 1

cii cnt code

Serv1 ce Code

L> 1 spatcher channel Stack

Channel stack

Figure 1

1 Client Code Fl Service Code

î î





ic1i entMessageForaatter

loi spatchMessageFo matter


Toispatchoperat i onselector

loi spatchMessageinspector


Figure 2

Figure 3


Applies To

Add via Config File

Add via Attribute

Add Programmatically


Service only





Client and Service




Client and Service




Client and Service


Table 2

ration files, attributes, or programmatic means. Here are a few rules-of-thumb I would suggest. You might choose configuration files when the interceptors to be added are optional and you want the flexibility to add or remove them after the service or corresponding proxies have been deployed. Attributes should be used when you want to inject an interceptor. These types of interceptors might be required logic that should never be removed after deployment. Lastly, you might consider adding behaviors and their corresponding interceptors programmatically when you need to optionally load them depending on some conditional logic that is evaluated at runtime.

Now that we've covered the key architectural aspects of WCF that allow for the injection of interception logic through custom behaviors, let's dig into some code.

How To Log Messages Received at the Service

In this section I'll show you how to use a Message Inspector (IDispatchMessagelnspector) and a configured Service Behavior (IServiceBehavior) to create a common "cross-cutting" behavior that logs messages. The service in this example is hosted in IIS, so you won't see any calls to ServiceHost. Additionally, while we could implement these interfaces on separate classes, I've chosen to implement both the interceptor and behavior interfaces on the same class. Such an approach may or may not make sense for your particular needs. You may, for example, want to implement interceptors in separate classes so your behavior class can load more than one interceptor.

Before I go any further I should also point out that the following example is primarily intended to hint at the possibilities for using message inspectors. Regarding the specific need to log messages, we could also use the WCF trace facility enabled via the MessageLoggingElement class in the System.ServiceModel.Configuration namespace. With that approach, you can alter a configuration setting in your Web or app config file and view the logged messages via the ServiceTraceViewer.exe tool. The following approach essentially captures the same information, but would give you more control over how the intercepted request message might be handled. For example, you could choose to send all outputs from a Web farm to one central location. Now that I've gotten that out of the way, let's look at some code.

In Listing 1 you'll see a partial listing for a class named InsertLogging that inherits from Behavior-ExtensionElement. This class also implements the IDispatchMessageInspector and IServiceBehavior interfaces.

The most appropriate interception interface to use when you need to modify, capture, or inspect messages on the service side is IDispatchMes-sageInspector. With this interface we can add our common logic into the AfterReceiveRequest and BeforeSendReply methods. The former is used to intercept messages and process them after they've been received from the channel and before they're sent on to the service code. The latter is used to process reply messages prior to sending them back to the clients. In Listing 1 you can see that I'm using Microsoft's Enterprise Library Logging Application Block to write the entire request message to some location. You can configure the Logging Block to write such entries to the event log, a database, a message queue, a text file, or other locations. Let's move on to see how this interception logic is loaded.

Listing 2 shows how the IServiceBehavior interface is implemented on the InsertLogging class. Here you can see that the only method into which I have added code is ApplyDispatchBehavior; the remaining two methods, Validate and AddBinding-Parameters, aren't relevant to this topic.

In Listing 2 you'll see that I iterate through each of the ChannelDispatchers associated with the ServiceHost, and then loop through all of the EndpointDispatchers that are found on each ChannelDispatcher. From this you can surmise that a service has one or many channel dispatchers, and each channel dispatcher could have one or many endpoint dispatchers. Since I want to intercept all messages flowing into each and every operation that a service exposes on each of its endpoints, I can add a reference to my interceptor at this point. You can see that after a reference to an EndpointDispatcher is acquired, a reference to the IDispatchMessageInspector class (i.e., the Insert-Logging class) is added to endpoint dispatcher's MessageInspectors collection.

Now that you've seen how to use an interceptor to create common logic (see Listing 1), and how to use a behavior to load that interceptor (see Listing 2), let's see how the behavior can be instructed to load via configuration files. You may first want to refer back to Listing 1 to see that the InsertLogging class inherits from the BehaviorExtensionElement class; this is the first thing you'll need to do if you want to use configured behaviors. When this is done, you must override that class's BehaviorType property and CreateBehavior method, as is shown in Listing 3.

The BehaviorType property in Listing 3 returns the type of behavior, which happens to be Insert-Logging. CreateBehavior is a "creational method" that returns an instantiation of a new InsertLogging object. Altogether, this provides the configuration system the information it requires to load the behavior class at the appropriate time.

Let's move on to see what you'll need to put in your configuration files to associate a behavior with a specific service. The first part of the system. serviceModel section from web.config is presented in Listing 4.

The key thing to notice in Listing 4 is the behav-iorConfiguration attribute. This tells the configuration system that a specific behavior, in this case one named LogBehavior, should be configured for use with this service. Listing 5 shows the behaviors section where you can see the actual definition for that behavior. Note that it has an element named LoggingBehavior, which indicates the "extension" to be associated with LogBehavior.

Listing 5 shows that the behaviorExtensions element contains a directive to add a custom .Net type named WCF.Behaviors.InsertLogging that can be found in the assembly named WCF.Behaviors. If you have set up your configuration file properly then the WCF runtime will acquire this information prior to opening the ServiceHost and will execute the logic found in Listing 3 and then the logic in Listing 2. If all has gone according to plan up to this point then when a message flows into any service endpoint, the common logging logic found in Listing 1 will be executed.

How To Inject Client Information into the SOAP Headers

Now let's see how we can use a client-side Message Inspector and a Contract Behavior so that we can track which applications use a given version of a contract. Let's say that we always want to enforce this behavior, so we decide to use attributes to tell the WCF runtime to always load the behavior on the client. Listing 6 shows a portion of a class named InsertClientInfo. Notice that it inherits from the Attribute class and also implements IClient-MessageInspector and IContractBehavior.

In summary, the logic in Listing 6 creates a custom MessageHeader using the ClientInfo type (see Listing 9), and adds that header to the request message. This all occurs before that message is sent through the proxy's channel stack and over the wire to the service. To put this interceptor into the WCF runtime on the proxy side, we can create code in the ApplyClientBehavior method so that a reference to the InsertClientInfo class will be added into the MessageInspectors collection of the proxy's clientRuntime. This is shown in Listing 7.

Now we have to alter the client proxy code so the ApplyClientBehavior method will be invoked. To do this we can either edit the output file produced by Svcutil.exe, or if we use the Visual Studio IDE to add a service reference to a project, we can edit the .cs file that it adds. Listing 8 shows how an attribute may be added to the code for the client proxy.

In this case, I used Visual Studio to add the service reference; this is why you see information from the CodeDom. Since I want to capture client information for all calls to a given service contract, I have to know the name of either the service interface class or the class that implements this interface. Lucky for me, I happen to know that the interface is named IBar-gainAirService. To tell the WCF runtime that it should load a behavior, the IBargainAirService interface has been decorated with the [WCF.Behaviors.Insert-ClientInfo] attribute. By choosing to decorate the IBargainAirService interface with this attribute, the effect will be that all classes in the proxy that implement this interface will have this behavior applied to them. Now, whenever a client opens a channel factory out to the service, the logic in Listing 7 will be invoked, and when the client sends a message out to the endpoint that contains this contract, the code in Listing 6 will step in to intercept the call. Pretty cool, eh?


We've covered a lot of ground in this article, from the WCF architecture that supports extensibility, to a few code samples showing some of the possibilities. I hope that you can now see how this powerful feature may be tapped to apply cross-cutting logic to your services. Perhaps you've even caught a glimpse of the endless possibilities that lie beyond. q


public class InsertLogging : BehaviorExtensionElement, IDispatchMessageInspector, IServiceBehavior

#region IDispatchMessageInspector Members object IDispatchMessageInspector. AfterReceiveRequest(ref System.ServiceModel.Channels.Mes-sage request,

IClientChannel channel, InstanceContext in-

stanceContext) {

LogEntry logEntry = new LogEntry();

logEntry.Message = request.ToString(); Logger.Write(logEntry);

return null; }

void IDispatchMessageInspector.BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) { ; } #endregion


#region IServiceBehavior Members void IServiceBehavior.ApplyDispatchBehavior(Servic eDescription serviceDescription, ServiceHostBase serviceHostBase) {

foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers) {

foreach (EndpointDispatcher endPoi ntDis-

patcher in channelDispatcher.Endpoints) {


sageInspectors.Add( this ); }

void ISemceBehavior.Validate(SemceDescription serviceDescription, ServiceHostBase serviceHostBase){ ;}

void IServiceBehavior.AddBindingParameters(ServiceD escription serviceDescription, ServiceHostBase serviceHostBase,

System.Collections.ObjectModel.Collection<ServiceEn dpoint> endpoints, System.ServiceModel.Channels.

BindingParameterCollection bindingParameters){ ;} #endregion

LISTING 3 #region BehaviorExtensionElement Members public override Type BehaviorType {

get { return typeof(InsertLogging); }

protected override object CreateBehavior() {

return new InsertLogging();


} // end of InsertLogging class

LISTING 4 <system.serviceModel> <services>

<service name="WCF.SOAPatterns.ServiceImplementation. BargainAi rService"

behaviorConfiguration="LogBehavior" > <endpoint address ="http://localhost:1777/WCF.SOAPat-terns.Host/BargainAi rService.svc"

binding="basicHttpBinding" contract="WCF.SOAPatterns.ServiceContracts. IBargainAirService" /> </service> </services>

LISTING 5 <behaviors> <serviceBehaviors > <behavior name="LogBehavior"> <LoggingBehavior/>

<serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="fa lse" />


0 0

Post a comment