Over 50 engaging recipes for learning advanced concepts of . Did you know that Packt offers eBook versions of every book published, with PDF and ePub . Chapter 6, WCF Recipes, explains uploading files using streamed mode. Thank you very much for downloading programming wcf services. programming wcf services is available in our digital library an online access to it is set as. WCF 4 Recipes Functional Fun If your WCF service is unexpectedly tonalt said For me the reason WCF 4 Recipes ¼ PDF Download eBook free from None.
|Language:||English, Spanish, German|
|Genre:||Health & Fitness|
|ePub File Size:||29.33 MB|
|PDF File Size:||12.87 MB|
|Distribution:||Free* [*Regsitration Required]|
WCF 4 comes with a wide range of specific features as follows: . services. Recipes here demonstrate various scenarios of generating a WCF service proxy and. It will also address the business drivers that dictate the need for these WCF features, as well as ws//04/discovery/mmoonneeyy.info to say that building an enterprise application without transactional support is a recipe for failure. Recipe demonstrates how to asynchronously consume a WCF A19F- CCBD9B/mmoonneeyy.info
For some user scenarios, we will also need to add a custom SoapHeader into the WCF service message so as to exchange additional information mostly for communication purposes. NET, and Silverlight can be found at www. The data that is used in data binding scenarios is in-memory data, that is, objects. Using Expression Blend 4 for sample data generation Expression Blend 4 contains a feature that is capable of generating the sample data while developing an application. NET 3. With the WCF coming in.
Kris van der Mast, an active and dedicated moderator at the official ASP. He's a well-known community member of several Belgian user groups. Kris is also a speaker for user groups in Belgium and abroad. You can find his blog at http: Kris currently works for Ordina Belgium, a consultancy company, as a senior. NET developer and architect. He also provides courses to clients in his specialization and technical interest—web technologies. Table of Contents Preface Chapter 1: Endpoint, Binding, and Behavior 27 Chapter 3: Service Discovery and Proxy Generation Introduction Creating a typed service client Choosing a specific type for representing a collection parameter Reusing types between service and client Customizing an auto-generated service proxy class in Visual Studio Building an ad-hoc auto-discoverable service Using managed ServiceDiscovery Generating a service proxy in code Customizing auto-generated service metadata 72 76 83 83 84 88 90 94 96 99 Chapter 5: Channel and Messaging Chapter 6: Dealing with Data in Service Chapter 7: NET membership provider Sending a clear text username token over unsecured HTTP transport Using transport and message security at the same time Authorizing through declarative role-based access control Impersonating with a client caller identity Adding multiple tokens in a service request supportingToken ii Table of Contents Supplying dedicated credentials for firewall or proxy authentication Securing a dynamic SoapHeader Chapter 8: Concurrency Chapter 9: Interoperability Chapter NET-based application programming interface for building and running connected systems.
It enables secure and reliable communication among systems within an organization or across the Internet. This book deals with the difficult issues faced by a.
Chapter 2, Endpoint, Binding, and Behavior, focuses on the basic building blocks of a WCF service, including endpoint, binding, and behavior.
The recipes in this chapter demonstrate how to create various kinds of services by using the proper combination of these building blocks. Recipes here demonstrate various scenarios of generating a WCF service proxy and introduces the service discovery feature in WCF 4.
Chapter 5, Channel and Messaging, digs into the channel layer of WCF programming and shows how to build WCF server and client applications through channel-layer components. NET DataTable objects in service operations. Chapter 7, Security, demonstrates how to utilize the built-in WCF security features such as service authentication, authorization, identity impersonation, message protection, and so on.
Preface Chapter 8, Concurrency, introduces some typical cases about managing the concurrency and performance behaviors of a WCF service, such as how to use throttling settings and how to use Visual Studio testing tools for service performance tuning. Chapter 9, Extending WCF Runtime, focuses on how to extend the existing components in the WCF programming model, such as customizing the default ServiceHost, using MessageInspector or MessageEncoder to intercept messages, customizing the service authorization logic, and so on.
Chapter 12, Diagnostics, introduces some useful tools and skills for troubleshooting and diagnostics in WCF service development, including how to capture WCF messages, how to debug a Windows service host, how to use WCF performance counters, and so on. What you need for this book Though all the samples in this book are C based, you don't have to be a very experienced C developer.
What is required is that you have a development machine with Visual Studio Professional or Ultimate edition and IIS installed, since the sample code is provided as Visual Studio solutions and some of them use IIS as host.
Who this book is for If you work with Windows Communication Foundation 4. With this book, you will be able to find quick and handy solutions for various kinds of service development scenarios using Microsoft Windows Communication Foundation 4. To follow the recipes, you will need to be comfortable with the. Here are some examples of these styles, and an explanation of their meaning. Code words in text are shown as follows: Words that you see on the screen, in menus or dialog boxes for example, appear in the text like this: Warnings or important notes appear in a box like this.
Tips and tricks appear like this. Let us know what you think about this book— what you liked or may have disliked. Reader feedback is important for us to develop titles that you really get the most out of. Customer support Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase.
Downloading the example code for this book You can download the example code files for all Packt books you have purchased from your account at http: If you purchased this book elsewhere, you can visit http: Errata Although we have taken every care to ensure the accuracy of our content, mistakes do happen.
If you find a mistake in one of our books—maybe a mistake in the text or the code—we would be grateful if you would report this to us. By doing so, you can save other readers from frustration and help us improve subsequent versions of this book. If you find any errata, please report them by visiting http: Once your errata are verified, your submission will be accepted and the errata will be uploaded on our website, or added to any list of existing errata, under the Errata section of that title.
Any existing errata can be viewed by selecting your title from http: Piracy Piracy of copyright material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously.
If you come across any illegal copies of our works, in any form, on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy. We appreciate your help in protecting our authors, and our ability to bring you valuable content. For distributed communication services, Contracts also play a very important role in making sure that the service consumers can co-operate with the service providers correctly. Technically speaking, SOAP Simple Object Access Protocol can be explained as a set of components that can be invoked, and whose interface descriptions can be published and discovered.
From an SOA perspective, with Contracts properly defined, service consumers can get an idea of how to work with the target service without knowing how the service is actually implemented. Working with Contracts As a unified communication programming platform, WCF provides complete support for Contract-related design in various parts of WCF service development.
ServiceContract and OperationContract are used to represent a Service and its operations' definition such as the operation collection and operation signatures. DataContract is used to represent an agreement of the data that will be exchanged between the service client and server. If the service designer wants to take full control over the data envelope transferred between client and server, they can use MessageContract to control the underlying service messages.
WCF also provides FaultContract for the service designer to declaratively associate custom Exception types to certain service operations, and the corresponding fault content will be returned when an error occurs.
This chapter provides seven recipes on how to work with various contracts in WCF service development. These include defining a one-way service operation that helps you get familiar with standard ServiceContract and OperationContract declaration.
Next, we will cover how to use FaultContractAttribute to associate a custom SOAP fault data type with certain service operations that need a customized error format.
With the third, fourth, and fifth recipes, we will focus on DataContract designing topics, such as DataContract versioning, using XMLSerializer for the DataContract types serialization, and the contract-first approach for DataContract generation.
The last two recipes describe how to use MessageContract to perform low-level manipulation on the service operations message formatting, such as returning arbitrary XML data as message content and adding a custom SOAPHeader through MessageContract class members. Defining a one-way Contract One-way also called diagram-style operation is a common pattern in distributed communication programming and is also one of the three supported message exchange patterns in WCF.
When using the one-way message exchange pattern, a client sends a message using a fire-and-forget exchange refer to the next screenshot. A fire-and-forget exchange is one that requires out-of-band confirmation of successful delivery. The message might be lost in transit and never reach the service. If the send operation completes successfully at the client end, it does not guarantee that the remote endpoint has received the message.
In those cases where the client only wants to send information to the server side, without taking care of the execution result, we can consider defining our WCF service operation as one-way style. Create the service interface or class type and add methods into it.
The following code snippet shows the complete one-way OperationContract definition: One-way operation cannot carry a return value but can only pass input parameters to the service. After the client sends out the service request, the client will wait until it gets the response that the request message has reached the service side. However, the response here is not the return value, but the protocol level ACK, which indicates that the request has reached the service but gives no idea of whether or how the request has been processed.
We can get further understanding on one-way operation via the following question: What is the difference between a standard void no return value operation and a one-way operation? Suppose you have the following ServiceContract implemented: Understanding this can help us to make better decisions about whether to use one-way operation or not.
There's more In addition to one-way operation, there are two other message exchange patterns that are widely used in WCF services.
They are the Request-response pattern and the Duplex pattern. The Request-response pattern is very similar to the standard function call that has an input parameter and return value. In a Request-response pattern-based WCF service operation call, a message is sent and a reply is received. The pattern consists of request-response pairs, as shown in the next figure.
This pattern is like a phone conversation, where each word being spoken is a message refer to the following screenshot. If we want to add new complex data types that will be transferred in service operations in a WCF service, we need to define it as a DataContract type so as to make it friendly to the DataContractSerializer engine.
NET serialization system supports backward-compatibility on custom data types naturally. However, sometimes we also need forward-compatibility for data types used in a WCF service.
Suppose that you have a service that exchanges some custom data types between clients. If one side updates the custom data type adds some fields or properties or uses a newer version, it is important to make sure that the other side without using the updated version of data can still work correctly with the updated data type instances. Make the custom data type we will use in our service communication implement the IExtensibleDataObject interface.
You can have a look at the article ServiceBehaviorAttribute. IgnoreExtensionDataObject Property for more information and is available at: After the DataContract type implements the IExtensibleDataObject interface, an ExtensionDataObject property is added; this property plays an important role in forward-compatible serialization.
And if the deserialized instance with some unknown data stored in ExtensionDataObject is serialized into the message later, DataContractSerializer will write out ExtensionDataObject into the message stream again. However, the ExtensionDataObject property is an opaque object to developers and we do not have means to manually read the data stored in it. See also ff Altering an operation message via MessageInspector in Chapter 9.
As a unified distributed communication development platform, it is quite common to support such kind of DataContract generation in WCF development. How to do it The next screenshot shows a simple sample schema that contains a simple enum and a complex data type definition: Following is the sample command on how to use the Svcutil. For the previous example, TestDataContractSchema.
NET 3. If you're familiar with ASP. You can generate a WCF client proxy and export metadata from service code. Here we just use it to generate serialization code from the given XML Schema. The DataContract we generated here includes two typical class types—a composite type and a simple enum type.
In most scenarios, people will define much more complicated data types in their services, and WCF DataContractSerializer does provide enough support for mapping between an XML Schema-based contract and. NET code-based types. First, we should make our data type ready for XMLSerializer.
This can be done by adding XML serialization attributes on our data types. Also, the auto-generated service metadata will output the data type schema based on the class's XML serialization attributes. For the User class mentioned in the previous code example, service metadata will use the schema as shown in the next screenshot to represent its XML format: By capturing the underlying SOAP message, we can find that the XML content of the serialized User object conforms to the metadata schema defined earlier, which is controlled by those XML serialization attributes applied on the user class refer to the next screenshot: However, this only covers the data members variables and parameters used in operation serialized in the underlying SOAP message.
Sometimes we also need to control the structure and format of the entire SOAP message. WCF introduces a MessageContract concept, which helps service developers to model the structure and format of the entire message of a given service operation.
Define a custom data type that represents the entire SOAP message body content. The following code demonstrates a sample MessageContract pair—one is for operation request and the other for operation response.
The serialization of such types still follows the rules for normal DataContract types. Also, it is important that operations which use MessageContract to control the SOAP envelope only have a single input parameter and return value.
This is because only that input parameter will be serialized as the entire SOAP request body, and the return value will be serialized as the entire SOAP response body. Each sub element under the optional Header is called a SoapHeader, which plays a similar role as the other headers, uses a certain network protocol's transmit package.
For some user scenarios, we will also need to add a custom SoapHeader into the WCF service message so as to exchange additional information mostly for communication purposes. Download from Wow! We need to define a custom type, which represents the SoapHeader that will be serialized in the service message. Here is a sample DataContract type that represents a custom header used for custom authentication: Next, we can apply the custom Header type into our service operation's MessageContract.
Also, since the header is added in MessageContract at design-time, the WCF auto-generated metadata will include the SoapHeader information, as shown in the following screenshot: If you use Visual Studio or Svcutil. Thus, when invoking the service operation, we can simply pass SoapHeader data as the operation parameter.
The following code demonstrates how the auto-generated service proxy invokes the operation with the custom SoapHeader assigned.
TestServiceClient ; TestProxy. WCF supports various means to add custom SoapHeader a into service messages. This recipe demonstrates using a custom type and MessageContract to add a custom SoapHeader statically. In addition to this, we can also use code to programmatically add SoapHeaders into service messages. For WCF service operations, exceptions are returned to the client through two steps: However, sometimes we want to encapsulate the raw exception information or return some user-friendly error to the client side.
FaultException is a new exception type that uses Generic to help WCF service encapsulate various kinds of custom error data objects in a unified way. FaultContract is used to formally specify the type of FaultException that will be returned from the target WCF service operation, so that the client consumers can properly handle and parse it.
First, create the custom error type that will be returned to the service client as exception information. The custom error type is defined as a standard DataContract type. Then, apply the custom error type to the service operation which will return this custom error type through a FaultContractAttribute. The following code shows a sample custom error type and the service operation that applies it: Finally, we need to add our exception handling code in the service operation's implementation and return the custom error type through the FaultException type see DivideWithCustomException method shown as follows: The FaultContractAttribute applied on the service operation will make the runtime generate corresponding metadata entries in the WSDL document as shown in the next screenshot.
Thus, the generated client proxy knows how to handle this custom error type. When invoking the operation, we can add code to handle the specific FaultException and get user-friendly error information from the Exception.
Detail property. WriteLine "Error: Since the custom error type used by FaultContract supports any valid DataContract type, we can define various kinds of custom exception data content from simple primitive types to complex nested classes. Service endpoints consist of ABC and a set of behaviors.
What is ABC? Behaviors also play an important role in WCF. By using behaviors, we can gain further manipulation over the WCF service at service or endpoint level. Endpoint, Binding, and Behavior This chapter provides eight recipes on using the built-in binding and behaviors to build various service endpoints, which represent some of the useful scenarios in general WCF service development.
Then, we will use two built-in bindings NetMsmqBinding and WSDualHttpBinding to demonstrate how to build a two-way communication and build a Publish-Subscribe pattern service through system bindings.
The fourth recipe shows how WCF allows a single service to expose multiple endpoints layered on heterogeneous transport and message settings. The last three recipes come from some common and tricky scenarios in service endpoint customization.
These services often use very simple and typical endpoint and binding definitions. However, every time we need to set up such a service, we have to define the same endpoint and binding settings again and again, which really adds much duplicated work. Fortunately, WCF 4. The steps for using a default endpoint are quite straightforward: Create a new Console Application project in Visual Studio targeting. NET Framework 4. Add the ServiceContract in the service project and implementation types we need in the service project.
We can use any valid ServiceContract and its corresponding implementation class here. For example, the following IHelloService service containing a single SayHello operation is used in our sample service application here: Add service configuration entries for the service type defined in step 2 in the app.
We do not need to define any endpoint and binding configuration here. The following screenshot demonstrates the necessary service configuration elements: Start a ServiceHost and specify the service type we want to run see the following code: Open ; Console. The magic behind scene is the Default Endpoints feature. When we start a WCF 4. The default endpoints will choose the proper binding based on its endpoint address the URL scheme by looking up a protocolMapping list predefined in the system configuration store within the.
NET 4 Machine. The following screenshot shows the protocolMapping list: For our previous example, since the endpoint address uses the HTTP scheme derives from the baseAddress , the runtime will choose the BasicHttpBinding according to the protocolMapping list.
By using the DumpEndpoint function, we can confirm that Default Endpoint with BasicHttpBinding has been correctly set up in the previous case refer to the next screenshot.
Open ; DumpEndpoint host. Endpoints ; ……………. Address, sep. Name, sep. Contract ; Console. WriteLine be. For example, we define the following anonymous binding configuration, which does not have an explicit name. Any endpoint that uses BasicHttpBinding will adopt the setting in this anonymous binding configuration. And the Microsoft. NET framework has also provided managed programming interfaces for developers to develop distributed applications based on MSMQ.
However, it is still a bit complicated and time consuming for developers to build a complete distributed service through the raw or encapsulated MSMQ programming interface. As the new unified communication development platform on Windows, WCF provides more convenient means for developing a distributed service over the underlying MSMQ component.
NET Framework System. Messaging namespace that encapsulates the raw MSMQ programming interfaces visit http: To make the WCF client and service perform two-way communication over MSMQ, we need to set up two MSMQ-based endpoints—one for the service to receive client requests and the other for the client to get responses. The following code snippet shows the sample ServiceContract one for the service and another for the client: Create the MSMQ queues on the client and server machines.
There are two means for us to create the queues. One way is to use the MMC snap-in. There are various ways to start up this snap-in, but the easiest is to open the Windows Computer Management utility in Administrative Tools, expand the Services and Applications section of the tree view on the left, and select the Message Queuing node.
This is also a great way to verify that MSMQ is installed on a particular machine. Another way is to create the queue programmatically, is as shown in the following code.
In the sample service here, we will create the MSMQ queues in code: Exists qName MessageQueue. After the message queues have been created, we can start configuring the service and client endpoints and map them to the underlying MSMQ queues.
For the receiver side, the service endpoint should use NetMsmqBinding and set the address in net. The following screenshot shows a sample service endpoint configuration: The private in the endpoint address indicates that the MSMQ queue is a private queue and NotificationReceiver is the queue name. The sender side will need to configure the client endpoint that uses the same configuration as the service endpoint at the receiver side, which is done as follows: How it works Messaging programming interfaces.
However, in some cases, if you need to establish communication between raw MSMQ application and WCF-based application, there is another built-in binding called MsmqIntegrationBinding, which is suitable for such scenarios.
You can have a look at the article How to: In WCF service development, the Publish-Subscribe pattern will also help in those scenarios where the service application will expose data to certain groups of clients that are interested in the service and the data is provided to clients as a push model actively instead of polling by the client.
This recipe will demonstrate how to implement the Publish-Subscribe pattern in a WCF service through dual binding. Getting ready The Publish-Subscribe pattern is widely adopted in various application development scenarios and there are many different kinds of descriptions for this pattern. Refer to the following links for more information: The first thing to do is to design a ServiceContract that supports PublishSubscribe pattern.
The following IPublicBillboard interface represents a sample contract for publishing some announcements to client applications that are interested in the service.
Also, a session has been enabled here so that the service can conveniently identify client callback channels through their sessionId. When implementing the ServiceContract, Subscribe will cache the callback channel via the client sessionId so that it can notify the client later by invoking the callback channel. Single ] public class PublicBillboard: Add sessionId, OperationContext. If there is already a callback interface with the same sessionId cached, the code will remove the existing one first.
In the service endpoint configuration, it is important to select a duplex binding. At the client side, we need to provide a type that implements the callback interface and supply this type instance when initializing the service proxy, which is done as follows: Form, BillboardProxy.
Subscribe ; btnSubmit. In the end, the service operation can selectively notify some or all of the clients proactively refer to the Announce operation shown as follows: GetAnnouncement string. Single, so that all the clients will share the same service instance. Enabling the session makes the service be able to differentiate clients by their sessionId. The following screenshot shows the service console, which prints out all new announcements received from the client.
At the client side, the callback function simply updates the Forum UI and prints the new announcement in the textbox control. Both the service callback operations are marked as one-way style. If we need to expose it via another different transport layer, we will probably have to add additional code to implement the new endpoint.
The WCF programming model separates the service implementation and underlying transport layer so that we can conveniently expose a single service implementation via multiple heterogeneous endpoints with different a transport layer and binding configuration.
First, we make sure our ServiceContract is ready for various endpoint bindings we want to use to expose it. The following sample contract is ready for most built-in bindings: The following code is the implementation of the CounterService: Single ] public class CounterService: Finally, we need to add the various endpoints and bindings in the service hosting code.
None ; host. None, false ; host. None,false ; 41 Endpoint, Binding, and Behavior host.
Client applications can use any of the exposed endpoints to consume the service. The sample client uses ChannelFactory to construct the client channel to consume the service: The following code shows a sample operation that is ready for exchanging POX-style messages.
Message class as the only input parameter and return value. For the service endpoint, we will need to apply a custom binding on it. The following screenshot shows the complete definition of our custom binding: After the service endpoint has been configured, we can start the service and consume it with POX-enabled clients.
For the service side, we can directly get the XML content from the input Message parameter. When returning the result, we also need to construct a Message instance and assign it the proper HTTP properties, if necessary. The following code demonstrates a simple message processing scenario: WriteLine reqMsg. CreateMessage MessageVersion. None, string. SayHello reqMsg ; Console. WriteLine repMsg.
GetBody ; How it works Also, the System. Message type allows us to freely construct arbitrary XML-style messages for service requests and responses. However, some non-WCF service platforms may not expose this header. When working with this kind of service client or service, we will need to prevent the WCF message engine from generating the timestamp header.
Using WSHttpBinding as an example, we can create a customized binding that derives most of the setting of the built-in WSHttpBinding but suppresses the timestamp header generation. The following code snippet demonstrates how to create the CustomBinding and configure the certain binding element to disable timestamp header generation. It then sets the IncludeTimestamp property to false.
Finally, we can apply this CustomBinding to any endpoint that needs to suppress the timestamp header. Since the timestamp header is a security feature that performs a message-replaying check, the WCF programming model exposes this setting through the SecurityBindingElement type. However, only setting the SecurityBindingElement. By comparing the underlying SOAP messages, we can find the obvious difference in the SoapHeader section before and after we disable the timestamp header generation.
The next screenshot is a SOAP message captured before removing the timestamp header: The following screenshot is for a SOAP message captured after removing the timestamp header: SoapHeader has a mustUnderstand attribute that indicates to the target endpoint or intermediate message processor whether the SoapHeader must be processed. By default, a WCF endpoint will perform validation on all the SoapHeaders within incoming messages, and if there are any unknown SoapHeaders not predefined which have a mustUnderstand attribute as 1 or true , a validation exception will be raised by the runtime.
However, sometimes it is useful to suppress this validation so that the WCF service or client proxy can gracefully handle unknown SoapHeaders that are dynamically added. Getting ready If you are not familiar with SoapHeaders and the mustUnderstand attribute, or how to set this attribute via the WCF programming model, you can take a look at the following references first: MustUnderstand Property http: The steps are as follows: First, we need to create a MustUnderstandBehavior type instance and set its ValidateMustUnderstand property to false which can be done in the type constructor.
Endpoints collection to find the wanted endpoint. For the client proxy, we can directly use [ClientProxy]. Endpoint to get the endpoint instance.
The following code shows the complete steps for applying MustUnderstandBehavior in service hosting code: But, we can still use code to access them from OperationContext, as follows: Count ; foreach var header in OperationContext. Name, header. In this recipe, we demonstrated how to inject the MustUnderstandBehavior for a self-hosting scenario. In such cases, we can use a custom ServiceHostFactory class to add the behavior injecting code logic.
Another great feature is letting multiple endpoints listen over the same physical transport address. For example, you want to host a WCF service that has multiple endpoints exposed. The first thing we need to do is configure the service endpoints. We will still specify different values for the address attribute of the two endpoints. However, we will use a special attribute named listenUri to supply the physical address identical for both endpoints.
The following screenshot shows the usage of both attributes: It is also important to configure the client endpoint so that the client proxy or ChannelFactory can correctly locate the service endpoint. You can use the ChannelFactory.
Behaviors collection to inject the behavior in code, shown as follows: None ; SharedAddressService. Foo ; Alternatively, you can also use the element to supply the physical address in a configuration file, as shown in the following screenshot: Generally, we will use the address attribute to specify the URL on which the endpoint will listen.
The listenUri, on the contrary, represents the physical transport address the service endpoint listens on. Also, for the endpoints that share the same physical address, they will share the same service dispatcher and channel stack. Then, how does the WCF runtime differentiate these operation requests when there are multiple endpoints listening on a single physical address?
The answer is WCF runtime will try to resolve the request target by the combination of two parts: See also ff Creating a multiple-endpoint service 53 3 Hosting and Configuration In this chapter, we will cover: After developers complete the service development, we will need to deploy the service so as to make it available to all the client consumers.
In the real world, there are various service deployment scenarios available, which will result in different deployment and configuration requirements on the service configuration or the hosting environment. As an enhanced service development platform, WCF provides rich, built-in support on service hosting and configuration that can fulfill most of the existing deployment demands and requirements.
For example, the most popular IIS hosting approach can provide high availability and stable service for local intranet or public internet-based deployment cases.
The Windows service-hosting approach makes WCF service hosting easier to integrate with existing background scheduled tasks, and the self-hosting approach provides the most flexibility and customization points for service deployment in a production environment.
Hosting and Configuration In this chapter, we will look at seven recipes on various WCF hosting and configuration scenarios. This is followed by two customized service-hosting cases—including a custom ServiceHostFactory and a dedicated singleton-instance hosting.
Hosting a service in a console application When creating a simple demo program for. NET framework, we will probably choose a console application. At the same, when talking about WCF service hosting, the console-hosting scenario is the most convenient one, which is especially handy and useful when we want to do some quick demo or testing on some WCF functionality.
Create a. Visual Studio provides various project templates for creating a. NET framework-based application. For our sample console-hosting service here, we will choose the Console Application project type from the Visual Studio New Project wizard.
Add a new WCF service into the project. Add code into the Main function to start up the WCF service. The following code shows the typical Main function that starts up a WCF service in a console application: WriteLine "press any key to stop service host The following code shows the sample ServiceContract and implementation class used in this recipe.
In addition to the Contract and service type, the IDE will also insert a default configuration setting for the endpoint that can be exposed through the service. Metadata can be exposed to a client through many different ways, including using a HTTP-based static metadata endpoint, using dynamic metadata discovery, using custom metadata generation, and so on.
In this chapter, we will go through eight recipes focusing on WCF client proxy generation and metadata publishing and discovery. The first four recipes demonstrate the typical service proxy generation scenarios and how to apply some special configuration options on the generated service proxy components. The fifth, Building an ad-hoc auto-discoverable service, and sixth, Using managed ServiceDiscovery, recipes show the new auto-discovery feature of WCF 4. The last two recipes focus on the customization scenarios of WCF service metadata and client proxy generation.
Creating a typed service client WCF services can be consumed by a client through various means. If our client application is also built upon. This recipe will show you how to create a typed service proxy through WCF service metadata. We will go through the typed service proxy generation steps via a simple WCF service that is hosted at the address http: Following are the detailed steps: Get the WSDL metadata of the targeting service.
For our sample service, we can directly get the service metadata at the SVC endpoint file from the previous address. We can simply do it through the Add Service Reference command in the project context menu item, in the Solution Explorer pane. Create the proxy class and review the generated components. The main class in the proxy components is the ServiceClient type highlighted in the previous screenshot.
If we look into the detailed code of this class, we will find that it is derived from the System. The following code snippet shows the entire Service1Client class used in our sample project: DebuggerStepThroughAttribute ] [System. GeneratedCodeAttribute "System. ServiceModel", "3.
EndpointAddress remoteAddress: Binding binding, System. The following command shows the simplest syntax for creating a WCF typed service proxy from a given metadata location: NET object into raw XML or binary format at the server side and deserialize it into an object of the mapping type at the client side.
We will usually use an array or collection-like type as parameter or return value type in a service operation. When calling such operations, the client-side proxy will need to define the corresponding types that will match the parameters or return values.
Here we will demonstrate how to specify the collection parameter type when generating the service proxy in Visual Studio. The detailed steps are as follows: When using the Add Service Reference wizard, we can click on the Advanced button to launch the advanced configuration panel, which contains those additional settings that control service proxy generation.
Choose the expected type from the given Collection type drop-down list. We can choose the collection types from a combo box that contains all the available types. List, Generic. LinkedList, and so on. The following screenshot shows the Collection type selection drop-down list. After specifying a custom collection type, the Add Service Reference wizard will generate the proxy class that uses the selected type to represent any collection-based parameters or return values in service operations.
For example, suppose the target service has the following ServiceContract: As mentioned in the Create a typed service client recipe, we can use Svcutil. When using Svcutil. For example: When generating a WCF client proxy through the Visual Studio Add Service Reference context menu item, it will help to generate some skeleton types that have the same serialization format with the custom types used in the server-side service at the client- side instead of directly using the server-side types.
However, sometimes we will need to reuse the existing types used at the server side instead of using the auto-generated skeleton types. The first thing we need to do is gather all those custom types used in our WCF service operation in one or several class library assemblies. This can help separate them from other service definition-related code and make them more convenient to be reused. For our sample WCF service, we will use a single assembly with the custom type defined as follows: SearchResult type in the service operation as shown in the following code: To make the custom types available to the client application that needs to consume the WCF service, we need to reference the assembly first, which can be done via Add Reference in the Visual Studio Solution Explorer pane.
In the previous screenshot, the ClassLib assembly is the shared class library, contains the custom types that need to be shared between the WCF service and client projects. Specify the assembly for looking up reusable types when generating the WCF service proxy in Visual Studio. As the previous screenshot shows, the advance options in Visual Studio's Add Service Reference UI has provided a Reuse types in referenced assemblies option that can let developers choose the assembly for probing reusable types between the server-side service and the client proxy.
After the service proxy is generated, we can open the main proxy class code to verify that the types defined in the centralized assembly have been used in the auto- generated service proxy as shown in the following code. The type probing is based on the WCF service operation's method signature such as parameter type and return value type or other types marked as knowable types.
Also, such kinds of assemblies being probed must be referenced by both client and service projects as shown in the previous figure.
By using the type reusing functionality, developers can avoid generating redundant and duplicated skeleton types in client projects that will consume WCF service projects using custom types. However, sometimes we will need to do some customization or adjustment on the generated proxy classes, such as add some custom methods, manipulate some of the method signature, or add additional member properties in the proxy class.
In this recipe, we will cover the way to manually modify the auto-generated WCF service proxy class in a Visual Studio project. In this recipe, we will look at the steps to customize an auto-generated WCF service proxy in Visual Studio by adding custom code. This is quite straightforward and we can just refer to the steps mentioned in the Creating a typed service client recipe.
After generating the service proxy and expanding the service reference node in Visual Studio, it will show you the view shown in the following screenshot: Also, this time we will need to inspect the main class of the service proxy in the Reference. The following code snippet shows the main class definition in our sample WCF service proxy: Get the main proxy class and create a partial class file to extend the main proxy class.
The next step is to add our customization code, which will extend the auto-generated service proxy class. To do this, we need to add a partial class file into the project and define a partial class with a name identical to the auto-generated main service proxy class shown previously.
The following code fragment shows the partial class definition in our sample client project: Parse xelm. Now that the default generated service proxy class has been extended via our partial class definition, we can use the custom member functions defined in the partial class on the proxy instance. As the following code snippet shows, the code for invoking the service operations through a service proxy instance remains the same as before: Service1Client ; Console.
WriteLine client. GetIntData 33 ; 95 www. Here we used a partial class file to extend the WCF auto-generated service proxy type. The partial class Service1Client is identical to the auto-generated service proxy type and has a custom method called GetIntData. The GetIntData method will call the auto-generated GetData service operation and do some post-processing on the return value before returning it to the caller. We can also add other custom methods or properties into the partial class so as to further extend the auto-generated proxy class.
When using the main proxy class to consume the WCF service, we can call any of our custom-defined members instead of the auto-generated operations so as to include our custom code logic seamlessly in the client-side code.
The advantage of this approach is that our custom code will be combined with the auto-generated proxy code and compiled together, which makes the proxy caller able to use our extended proxy members properties or functions seamlessly.
Another highlight is that by using a partial class file, the custom code to extend the proxy class will not be discarded when you update the WCF proxy via the Update Service Reference context menu item in Visual Studio. In such cases, it is quite important to let the service client be able to dynamically discover the service location.
Fortunately, WCF 4 provides a new feature called service discovery, which can properly address this issue. The discovery feature enables services to be discoverable at runtime in an interoperable way using the WS-Discovery protocol. WCF services can announce their availability to the network using a multicast message or to a discovery proxy server.
Client applications can search the network or a discovery proxy server to find services that meet a set of criteria. In this recipe, we will cover how to build a simple and powerful ad-hoc auto-discoverable service through the service discovery feature.
The service discovery feature in WCF 4 is based on this specification. Our sample service will use the WCF 4 built-in discovery endpoint to demonstrate the steps for creating a WCF service with ad-hoc discoverable ability: Enable the auto-discovery feature on the WCF service.
The first thing to do is make the WCF service application auto-discovery ready.
For ad-hoc auto-discoverable services, we can simply add an udpDiscoveryEndpoint into the service's endpoint collection. The following screenshot shows the complete service configuration with discovery endpoint and corresponding behaviors defined. Add dynamic service-discovering code in the client application. However, instead of using a static endpoint address, we can use the DiscoveryClient class to locate the service endpoint address programmatically.
The following code demonstrates how to dynamically find an auto-discoverable service and assign the dynamic EndpointAddress to client a proxy: Address; Console.
CalcServiceClient ; client. Also, like the service-side, the client application also needs to configure the udpDiscoveryEndpoint entry. The ad-hoc auto-discovery feature in WCF 4. As used in the sample service, by applying udpDiscoveryEndpoint in the service, the runtime will start a UDP server for listening to any discovery requests from client applications.
And the udpDiscoveryEndpoint within the endpoint collection represents the built-in Discovery endpoint which will serve the discovery requests from a client application that is looking for the hosting service. Also, the discovery communication between client and service conforms to the WS-Discovery specification. However, sometimes we may need a more advanced service-discovering functionality for our WCF service. For example, we may need to make the auto-discovery feature go across different subnets in the local network or we may need to perform some filtering against all the discoverable services.
Fortunately, WCF provides interfaces for us to build a custom discovery proxy for service announcement and service probing. In this recipe, we will show you how to create a custom service-discovery proxy through the WCF built-in discovery extension types. Create a custom DiscoveryProxy type. The first thing to do is create a custom type derived from the DiscoveryProxy class.
This class is the main component for processing WCF service publishing and service-probing requests. It is also required that the custom DiscoveryProxy class be defined as a singleton service, so that there is a single entry point for all the service announcement and probing requests.
The following code snippet demonstrates the custom DiscoveryProxy class definition and those core functions for maintaining the service list: Multiple ] public class DemoDiscoveryProxy: Remove discMetadata.
ContractTypeNames ; lock this. Address ; lock this. The following code snippet shows the implementation of service probing and announcement operations: Launch the custom DiscoveryProxy type in a host application. The next step is to set up the custom DiscoveryProxy in a host application, just like a standard WCF service. Here we use a console application to host the custom DiscoveryProxy through the following StartDiscoveryProxy function: AddServiceEndpoint discoveryEndpoint ; host.
AddServiceEndpoint announcementEndpoint ; host. Open ; Having the custom DemoDiscoveryProxy running, we can let our WCF services use this discovery proxy for announcement registration. The following screenshot shows the configuration fragment of a sample service that uses the custom DemoDiscoveryProxy as the new announcement center: Probe for the service from the custom DiscoveryProxy in client applications. At the client side, we will now change the service-probing code to use the new DemoDiscoveryProxy for locating the WCF service, too.
The following code shows the sample client application that uses the new probing endpoint for searching the service. Whenever it receives an announcement request from the WCF service, it will determine whether to add the service into the dictionary or remove it, based on the request type. Since all the service-announcement and probing interfaces are of asynchronous pattern, to simplify the implementation, we create a dummy IAsyncResult class that always marks itself as Completed at the construction time, so that the announcement and find operations in DemoDiscoveryProxy still work in synchronous manner.
Here is the complete definition of the DummyAsyncResult class: Both of them actually import the metadata from the WCF service and generate proxy types from it. In addition to these kinds of static proxy generation approaches, WCF also provides powerful a interface for programmatically creating service proxy types. To generate the client proxy types in code, we need to reference the necessary assemblies and import the proper namespaces. Following are the namespaces that contain those key types for generating the service proxy dynamically: ServiceModel; using System.
Description; using System. CodeDom; using System. Compiler; www. Locate and import the service metadata. WCF provides the MetadataExchangeClient class that can help import service metadata from a given metadata endpoint programmatically. Extract the target ServiceContract type for which we want to generate a client proxy. It is possible that the service metadata contains multiple endpoints and ServiceContracts. We need to find the expected one for which we want to generate the client proxy.
Generate source code of the service proxy from the extracted ServiceContract type and metadata. After the metadata is imported correctly and has identified the correct ServiceContract, we can use the. In our sample client, we will save the source code into a C code file. Compile the source code into a binary assembly. To make the service types executable, we need a further step to compile the proxy code into a.
NET assembly. The GenerateServiceProxy function in the following code snippet demonstrates all the previously mentioned steps: GenerateServiceContractType allContracts ; www.
UTF8 ; provider. GenerateCodeFromCompileUnit unit, sw, options ; sw. Add "C: Errors Console. WriteLine err. WriteLine "Service proxy has been successfully generated! There are two components that play a big role in the process of dynamic proxy generation. The first is the MetadataExchangeClient type, which exposes the programming interface for importing WCF service metadata in a.
NET-based application. Another key component is the. Also, by using the. NET reflection APIs together, we can directly load the dynamically-generated proxy types in code without hardcoding the code logic statically at design time.
And this auto-generated WSDL metadata can be easily customized through the IWsdlExportExtension interface so as to fit some special requirements in our service development. In this recipe, we will use a web-hosted WCF service with a metadata endpoint enabled as an example to demonstrate how to customize the auto-generated WSDL metadata. The IWsdlExportExtension interface provides extension points for injecting custom code logic in the WSDL metadata generation, while the IEndpointBehavior interface will make the custom extension type be able to inject into the target service endpoint's behavior collection.
OpenRead "d: Read fs,null ; fs. Close ; sd. If you're using a self-hosting scenario, it is quite straightforward to add the WsdlExportExtension object into the Behaviors collection of the target endpoint. For our sample service, since we use a web hosting scenario with a. The following code shows the custom ServiceHost and ServiceHostFactory implementation in our sample case: Apply the custom ServiceHostFactory into the. Finally, we need to change the ServiceHostFactory type of those.
When we request the metadata page of our WCF service, the runtime will go through all the endpoints on the service and generate the WSDL document for them. And during the metadata generation process of each endpoint, any IWsdlExportExtension components registered at the endpoint will be invoked and the custom code logic in each extension class is applied into the metadata. In the sample WSDLExporterExtension class, the ExportEndpoint function provides the WsdlExporter object from which we can enumerate all the ServiceDescription document instances generated by the metadata runtime and customize them.
And in the previous WSDLServiceHost type, it manually enumerates all the registered service endpoints and injects our custom WsdlExportExtension instance into the Behavior collection of those endpoints.
However, under the service-oriented design view, there are many raw components that construct the WCF client and service. All these raw components provide a Channel model that allows developers to develop WCF services at a very low level.
Instead of service operations and method parameters, we will work with raw Message objects directly at the Channel Model programming layer. Though the Channel Model programming adds more complexity, it does give much more flexibility and a clearer overview of how the WCF runtime works under the hood.
The first and second recipes demonstrate how to use ChannelFactory and the Channel object model to consume a WCF service. The last two recipes cover the usage of an underlying Message context of WCF service operation calls and shows how developers can add custom data into the raw Message layer of WCF service communication.
However, there are many cases in which we will need to get rid of this kind of auto-generated service proxy class. For example, we may need to directly reuse the existing types including the ServiceContract type and custom data types used in the service definition, or we might just need a lightweight component to invoke a service operation.
For such scenarios, we can use the ChannelFactory class to directly communicate with the target WCF service endpoint.
Define or import the ServiceContract types. The first thing we should do is to make sure that the client application has the ServiceContract type that is identical to the one used in the server-side WCF service. For our sample service, we will use a test ServiceContract as shown in the following code snippet: Build the ChannelFactory and a Channel against the target service endpoint. Given the ServiceContract type and any referenced types if necessary , we can start building the ChannelFactory and Channels for consuming the WCF service.
Typically, we will need to supply the binding and endpoint address of the target WCF service we want to consume. For our test client application, we will build the binding and endpoint address in code without loading them from the application configuration file App. The following code shows how to build the ChannelFactory and Channel, along with invoking the service operation through the generated channel: CreateChannel ; Console.
WriteLine "Data: The T generic parameter indicates the ServiceContract of the target service endpoint. By calling the CreateChannel method on the ChannelFactory object, we can get the Channel object on which we can invoke the service operations, defined in the ServiceContract.
In WCF, there are well-designed message processing stacks at both server and client sides. At the client side, creating channels is the responsibility of ChannelFactory and is used for sending messages.
These channels are responsible for getting the message from the layer above, performing whatever processing is necessary, and then sending the message to the layer below. The following figure illustrates this process. For example, we can get the underlying channel and close it as shown in the following code snippet: Close ; There's more Channel Factories and Channels http: Add async style operation definition into the ServiceContract type in the service client.
As described in Use ChannelFactory to consume a WCF service recipe, we need to import the ServiceContract definition into our client application that needs to invoke the service operation via ChannelFactory. And to make the ChannelFactory-based WCF client be able to invoke service operation asynchronously, the most important thing is adding the asynchronous pattern OperationContract into the ServiceContract type.
The following code demonstrates the sample ServiceContract in the client application that supports service invoking via both synchronous and asynchronous style. They are BeginAdd and EndAdd, which conform to the. Invoke service operations through the async style operation methods. After we have defined the asynchronous invoking-enabled ServiceContract type, we can simply use ChannelFactory and Channel to invoke the service operation in async mode, which is almost the same as what we do for synchronous invoking.
The following CallServiceAsync function shows a complete example of invoking a service operation synchronously: CreateChannel ; calc. EndAdd ar ; Console. The asynchronous service invoked here is completely implemented at the client side.
The WCF service side has no sense of whether the client application is using sync or async mode to call itself. Also, from the ServiceContract type in client we can find that the asynchronous operation signature completely conforms to the. NET asynchronous method pattern. For more information on. Likewise, there are also corresponding components at the Channel level for building a WCF service.
Though the Channel level-based service might not look as comprehensible and convenient as those built via ServiceContract and ServiceHost, it is no less powerful than the former. It is quite simple and straightforward and clearly shows how the WCF service and endpoint actually work under the hood at Channel level.
The first step is to construct a ChannelListener instance with binding and endpoint address information supplied. In our sample service, we will use a BasicHttpBinding with all the default binding configuration settings.
After the ChannelListener is constructed with proper configuration, we can open it and start listening for requests from client applications. Just like standard TCP socket programming, we can use AcceptChannel or BeginAcceptChannel to acquire a client-side request channel in either synchronous or asynchronous style.
Our sample service will use an asynchronous pattern for handling client-side requests. The following code snippet shows the complete application code of the sample ChannelListener service: Abort ; listener.
EndAcceptChannel ar ; channel. RequestMessage; Console. WriteLine "Message body: CreateMessage binding. MessageVersion, "http: Reply replymessage ; message.
Close ; request. Close ; channel. As the sample service shows, we create a ChannelListener instance, which acts as a connection point for accepting service requests from the client side.
When processing service requests, each request is associated with a certain Channel coupled with the ChannelListener at the initializing stage. Our sample service uses IReplyChannel, which is often used with IRequestChannel at the client side like most WCF service operations with input parameter and return value use. More information about Channel shapes can be found in the following references: Started from.
Get a reference to the message properties from OperationContext. The IP address information is embedded in the message properties transferred from client to server.
We can use the OperationContext. Current property to access those message properties in the service operation code. The following code snippet shows how to obtain the reference to message properties within service operation code: The IP address information is stored in a specific message property item, which is of the RemoteEndpointMessageProperty type.
The next remaining code shows how we can extract the RemoteEndpointMessageProperty instance from the message property collection and get the IP and port information: Name]; Console. WriteLine "Client Address: Address, remProp. Port ; How it works Our helper function uses the OperationContext class to access the RemoteEndpointMessageProperty object, which contains the IP address of the client consumer. Actually, WCF uses OperationContext to carry data and properties during the service operation call context.
In addition to this, we can also programmatically create a custom SoapHeader and add it into a WCF request dynamically. Create a custom SoapHeader instance. The first thing to do here is to generate an instance of the SoapHeader we want to add into the request message. GetUntypedHeader "ClientUser", "urn: Inject a custom SoapHeader object through OperationContext.
The following code snippet shows the complete steps for adding an untyped SoapHeader into a WCF client request: Add Userheader ; Console. Also, we can define a custom header type derived from the MessageHeader class instead of using the untyped MessageHeader-based SoapHeader.
In the server-side code, we can also conveniently extract the particular SoapHeader from the incoming OperationContext.
The following code shows how we can read the custom SoapHeader we added in the earlier sample client code: WCF supports transferring various kinds of data such as database records, custom data objects, XML document, and even raw binary data. In this chapter, we will go through different kinds of data transferring cases in WCF service development. We will then use four recipes to demonstrate how we can exchange various kinds of data in a WCF service operation.
And the last two recipes will cover the features related to WCF data serialization. The following screenshot shows the main window of the WPF application. For this sample case, we will put all the window UI definition within the XAML file so as to make the code focus on data binding functionality. The following screenshot shows the complete XAML template of the main window.
Also, the tbStringValue and cbBooleanValue elements have both been associated with a data binding expression so that they will populate the corresponding property from the DataContext object in their container UI element. Our sample application will use a button click event to perform the data binding task. Service1Client ; TestProxy. As the button click event handler in the previous section shows, we can assign WCF service- returned data objects to the DataContext property of any existing WPF UI elements so that the data objects become visible for data binding to any other sub UI elements nested in the container element.
And WPF uses the following data binding expression to locate the exact data member for populating values on the UI element. Data objects transferred as parameters or return value will be serialized from a. NET object into message content at the sender side, and deserialized back to objects on the other side. This can help reduce the complexity of types that will be transferred over WCF communication. WriteLine "String: StringValue, ct.
In addition to this, we can also explicitly return custom data of raw XML format. To return raw XML format data, the simplest way is using a. The following code shows the ServiceContract of the sample service: For data parameters or return values of. The following screenshot shows the response SOAP message of our sample service operation, which returns an XElement instance. The DataTable class is a member of the System.
Data namespace within the. NET framework class library. You can create and use a DataTable independently or as a member of a DataSet, and DataTable objects can also be used in conjunction with other. NET framework objects. There are various possible solutions for DataTable or DataSet transferring in a WCF service; we will go through the most common ones in this recipe.
Getting ready In our sample service, we will demonstrate several means to return data from a DataTable to client consumers. The sample DataTable consists of three simple columns, as shown in the following screenshot. Let's go through three commonly used methods for returning data from ADO.
If both the WCF service and client sides are built upon. We can directly use a DataSet as service operation argument or return type, and return our DataTable through a DataSet instance as the container. The following code snippet shows the operation that returns a DataTable through a container DataSet instance: Tables collection. Since a. WriteXml strwtr ; return XElement.
Parse strwtr. This is not quite efficient for binary data transfer, as the encoded Base64 string will increase the data size compared to raw binary bytes. In this recipe, we will use a sample service to demonstrate the steps necessary for applying MTOM message encoding for WCF service endpoints.
For ServiceContract or OperationContract, and the types used as parameters or return values, we need to make sure that they conform to the following two points: The following code snippet shows the sample OperationContract and the MessageContract type used as the return value of the operation: Apply MTOM encoding on the target service endpoint through binding configuration. However, the default declaration requires a developer to specify the ServiceKnownType statically in the source code.
For example, the IService1 ServiceContract in the following code snippet shows a sample ServiceContract that specifies a custom type Circle as an additional known type: Thus, it would be useful to provide such types of ServiceKnownType in a programmatic way so that developers or service administrators can conveniently configure the ServiceKnownType without the need to recompile the service code. In order to specify ServiceKnownType programmatically, we need to use the constructor overload of the ServiceKnownTypeAttribute class, which can let us specify a custom type and method name for supplying multiple ServiceKnownType.
GetKnownTypes method. Split ';' select Type. GetType strType. Whenever developers or service hosts want to change the ServiceKnownType, they can simply modify the appSettings entries as shown in the following screenshot without recompiling the ServiceContract code. In our sample ServiceContract mentioned in the previous section, the auto-generated WSDL document will include a schema that contains the XML complex type definition of the Circle and Rectangle classes shown in the next screenshot.
Thus, whenever the WCF service consumers generate WCF client proxy types from the metadata, those ServiceKnownType will also be detected and have corresponding types generated together with the service proxy classes. However, sometimes we will prefer using the XmlSerializer for data object serialization in a WCF service. For example, when talking to some non-. This is to produce a compatible DataContract between service and client more conveniently.
First, we need to decorate our custom DataContract types which will be transferred as parameters in the WCF service operation with certain XML serialization attributes see the SimpleData type in the following code snippet: After defining an XML serialization ready type, we can apply it in our service operation and, more importantly, add the XmlSerializerFormatAttribute on the ServiceContract type.
As our sample service code shows, we have applied both DataContractSerializer and XmlSerializer formatting attributes on the custom type. NET membership provider ff Sending a clear text username token over unsecured HTTP transport ff Using transport and message security at the same time ff Authorizing through declarative role-based access control ff Impersonating with a client caller identity ff Adding multiple tokens in a service request supportingToken ff Supplying dedicated credentials for firewall or proxy authentication ff Securing a dynamic SoapHeader Introduction Security is a big topic in distributed communication applications.
When the client consumers call a service operation through an intranet or the Internet, it is necessary to consider how we will secure the communication between the two sides, or how we can make sure that we are talking to the correct service or the correct client consumers. WCF provides a lot of built-in features for developers to address all these kinds of problems in service application development. The most commonly used WCF security features include authentication, authorization, and message protection signing and encrypting.
The first five recipes will focus on various authentication use cases, including Windows authentication, username authentication, and so on. These are followed by two recipes that introduce some role-based authorization and identity impersonation cases. In addition, there are also some special topics in the last three recipes—the multiple token recipe shows how to use the SupportingToken feature, the supplying dedicated credentials recipe shows how we can resolve WCF client authentication across an intermediate web proxy, and the securing dynamic SoapHeader recipe extends the Adding a dynamic SoapHeader into a message recipe in Chapter 5.
Setting up ad hoc Windows authentication over plain HTTP WCF supports various authentication types and Windows authentication is a common authentication method used in existing distributed communication components on the Windows platform.
In this case, you can create a binding in XAML called an element binding or element-to-element binding. This binding links both values. If needed, the data can flow bidirectionally. In the banking application, we can add a loan calculator that allows the user to select an amount and the number of years in which they intend to pay the loan back to the bank, including of course a lot of interest.
To build the loan calculator, we'll use Slider controls. Each Slider is bound to a TextBlock using an element-to-element binding to display the actual value. Let's take a look at the steps we need to follow to create this binding: We will build the loan calculator as a separate screen in the application.
Add a new child window called LoanCalculation. Within MainPage. In the code-behind's event handler for this Click event, we can trigger the display of this new screen with the following code: The UI of the LoanCalculation.
Each Slider control has set values for its Minimum and Maximum values not all UI code is included here; the complete listing can be found in the finished sample code as shown in the following code: As dragging a Slider does not give us proper knowledge of where we are exactly between the two values, we add two TextBlock controls. We want the TextBlock controls to show the current value of the Slider control, even while dragging.
This can be done by specifying an element-to-element binding as shown in the following code: This can be done using the following code: The code for the actual calculation that is executed when the Calculate button is clicked uses the actual value for either the Slider or the TextBlock. This is shown in the following code: The following screenshot shows the LoanCalculation.
An element binding links two properties of two controls directly from XAML. It allows creating a Binding where the source object is another control.
For this to work, we need to create a Binding and specify the source control using the ElementName property. Element bindings were added in Silverlight 3. Silverlight 2 did not support this type of binding. An element binding can also work in both directions, that is, from source to target and vice versa. This can be achieved by specifying the Mode property on the Binding and setting it to TwoWay.
The following is the code for this. In this code, we replaced the TextBlock by a TextBox. When entering a value in the latter, the Slider will adjust its position: Element bindings eliminate this need: Round e. NewValue ; AmountTextBlock. For more information on TwoWay bindings, take a look at the Using the different modes of data binding to allow persisting data recipe in this chapter.
Binding collections to UI elements Often, you'll want to display lists of data in your application such as a list of shopping items, a list of users, a list of bank accounts, and so on. Such a list typically contains a bunch of items of a certain type that have the same properties and need to be displayed in the same fashion. We can use data binding to easily bind a collection to a Silverlight control such as a ListBox or DataGrid and use the same data binding possibilities to define how every item in the collection should be bound.
This recipe will show you how to achieve this. In this recipe, we'll create a ListBox bound to a collection of activities. To complete this task, carry out the following steps: We'll need a collection of some kind. We'll create a new type, that is, AccountActivity. Add the AccountActivity class to your Silverlight project as shown in the following code: Now, we'll instantiate accountActivitiesCollection and fill it with data.
To do this, add the following code to MainPage. You can add more if you want to. Add the following code to the MainPage constructor to call the method you created in the previous step: We're going to need a control to display these AccountActivity items. If we build and run the application now, we'll see that a list of AccountActivity items is displayed as shown in the following screenshot: The first three steps aren't important for people who have worked with collections before. A class is created to define the type of items that are held by the collection, which is initialized and then items are added to it.
The default collection type to use in Silverlight is ObservableCollection. We're using this collection type here. For more information about this, have a look at the There's more The real magic happens in steps 4 and 5. In step 4, we are creating a ListBox, which has an ItemTemplate property. This ItemTemplate property should contain a DataTemplate, and it's this DataTemplate that defines how each item of the collection should be visualized.
So, the DataTemplate corresponds to one item of your collection: This means we can use the data binding syntax that binds to properties of an AccountActivity in this DataTemplate. An ObservableCollection is the default collection type you'll want to use in a Silverlight application because it's a collection type that implements the INotifyCollectionChanged interface.
This makes sure that the UI can automatically be updated when the collection is changed by adding or deleting an item. More on this can be found in the Enabling a Silverlight application to automatically update its UI recipe. The same principle applies for the properties of classes that implement the INotifyPropertyChanged interface. More on this can be found in the same recipe, that is, Enabling a Silverlight application to automatically update its UI. In this recipe, we're using a ListBox to visualize our ObservableCollection.
See also To learn how an ObservableCollection enables a UI to be automatically updated, have a look at the Enabling a Silverlight application to automatically update its UI recipe. Enabling a Silverlight application to automatically update its UI In the previous recipes, we looked at how we can display data more easily using data binding for both single objects as well as collections. However, there is another feature that data binding offers us for free, that is, automatic synchronization between the target and the source.
This synchronization will make sure that when the value of the source property changes, this change will be reflected in the target object as well being a control on the user interface. This also works in the opposite direction—when we change the value of a bound control, this change will be pushed to the data object as well. Silverlight's data binding engine allows us to opt-in to this synchronization process.
We can specify if we want it to work—and if so, in which direction s —using the mode of data binding. The synchronization works for both single objects bound to the UI as well as entire collections. But for it to work, an interface needs to be implemented in either case. This synchronization process is what we'll be looking at in this recipe. In this recipe, we'll look at how Silverlight does automatic synchronization, both for a single object and for a collection of objects.
To demonstrate both types of synchronization, we'll use a timer that adds another activity on the account every 10 seconds. A single instance of the Owner class is bound to the UI. Also, these activities on the account will be reflected in the list of activities. The following are the steps to achieve automatic synchronization: For the data binding engine to notice changes on the source object, the source needs to send a notification that the value of one of its properties has changed.
By default, the Owner class does not do so. The original Owner class is shown by the following code: To make this class support notifications, an interface has to be implemented, namely the INotifyPropertyChanged interface.
This interface defines one event, that is, the PropertyChanged event. Whenever one of the properties changes, this event should be raised. The changed Owner class is shown in the following code. Only two properties are shown as they are all similar; the rest can be found in the finished solution in the book sample code. To simulate updates, we'll use a DispatcherTimer in the MainPage.
With every tick of this timer, a new activity on the account is created. We'll count the new value of the CurrentBalance with every tick and update the value of the LastActivityDate and LastActivityAmount as shown in the following code: Now; owner. If no Mode is specified, OneWay is assumed. This causes updates of the source to be reflected in the target as shown in the following code: An Introduction to Data Binding Grid.
If we run the application now, after 10 seconds, we'll see the values changing. The values can be seen in the following screenshot: If we want the UI to update automatically when changes occur in the list when a new item is added or an existing item is removed , then the list to which we bind should implement the INotifyCollectionChanged interface.
Silverlight has a built-in list that implements this interface, namely the ObservableCollection. If we were binding to a List , then these automatic updates wouldn't work.
Working with an ObservableCollection is no different than working with a List. In the following code, we're creating the ObservableCollection and adding items to it: Update the Tick event, so that each new Activity is added to the collection: Add newActivity ; To bind this collection to the ListBox, we use the ItemsSource property. The following code can be added to the constructor to create the collection and perform the binding: With every tick of the Timer, a new activity is added and the UI refreshes automatically.
In some scenarios, we might want to view changes to the source object in the user interface immediately. Silverlight's data binding engine can automatically synchronize the source and target for us, both for single objects and for collections. Single objects If we want the target controls on the UI to update automatically if a property value of an instance changes, then the class to which we are binding should implement the INotifyPropertyChanged interface. This interface defines just one event— PropertyChanged.
It is defined in the System. ComponentModel namespace using the following code: The name of the property that has changed is passed as the parameter for the instance of PropertyChangedEventArgs. OneWay allows updates to be passed on to the target. For more information on binding modes, refer to the Using the different modes of data binding to allow persisting data recipe.
Whenever we do so, Silverlight's data binding engine will notice this and will automatically start to check if the PropertyChanged event is raised by an instance of the class. It will react to this event, thereby resulting in an update of the target.
Collections Whenever a collection changes, we might want to get updates of this collection as well. In this example, we want to view the direct information of all the activities on the account.
Normally, we would have placed these in a List. However, List does not raise an event when items are being added or deleted. This interface is known as INotifyCollectionChanged. We didn't directly create a class that implements this interface.
However, we used an ObservableCollection. This collection already implemented this interface for us. Whenever items are being added, deleted, or the collection gets refreshed, an event will be raised on which the data binding engine will bind itself.
As for single objects, changes will be reflected in the UI immediately. Cleaning up the code In the code for the Owner class, we have inputted all the properties as shown in the following code: Sometimes it's not even wanted. Therefore, implement the interfaces that are described here only when the application needs them. It's an opt-in model.
For example, if a user clicks on a Delete button on an item, it's essential that you know which item is clicked so that you can write the correct code to delete that item. Also, when a user wants to edit an item in a list, it's necessary that you—the programmer—know which item in the list the user wants to edit.
In Silverlight, there is a very easy mechanism called DataContext that helps us in this task. In this recipe, we're going to use the DataContext to get the data when we need it.
We're going to create a Details This Details To achieve this, carry out the following steps: We'll start by opening the solution we've created by following all the steps of the Binding data to collections recipe. Next, we open ActivityDetailView. Now, we open MainPage. Add the following C code to MainPage. DataContext ; activityDetailView. We can now build and run the solution.
When you click on the Details You can see the result in the following screenshot: For example, if we have a UserControl containing a Grid that has three columns, with a TextBox in the first two and a Button in the last column, and if the DataContext of the UserControl gets set to an object of the Person type, then the Grid, TextBox, and Button would have that same Person object as their DataContext.
To be more precise, if the DataContext of an item hasn't been set, then Silverlight will find out if the parent of that item in the visual tree has its DataContext set to an object and use that DataContext as the DataContext of the child item. Silverlight keeps on trickling right up to the uppermost level of the application. The data we need is the DataContext of the button we're clicking. The click event of this button has a sender parameter—the Button itself.
To access the DataContext, we cast the sender parameter to a Button object. To show the details window, all we need to do now is pass this object to the constructor of the details ChildWindow. You can learn more about data binding and the various possibilities it offers by looking at almost any recipe in this chapter. Using the different modes of data binding to allow persisting data Until now, the data has flowed from the source to the target the UI controls. However, it can also flow in the opposite direction, that is, from the target towards the source.
This way, not only can data binding help us in displaying data, but also in persisting data. The direction of the flow of data in a data binding scenario is controlled by the Mode property of the Binding.
In this recipe, we'll look at an example that uses all the Mode options and in one go, we'll push the data that we enter ourselves to the source. Getting ready This recipe builds on the code that was created in the previous recipes, so if you're following along, you can keep using that codebase. You can also follow this recipe from the provided start solution. In this recipe, we'll build the "edit details" window of the Owner class. On this window, part of the data is editable, while some isn't.
The editable data will be bound using a TwoWay binding, whereas the non-editable data is bound using a OneTime binding. The Current balance of the account is also shown—which uses the automatic synchronization—based on the INotifyPropertyChanged interface implementation. This is achieved using OneWay binding. The following is a screenshot of the details screen: Let's go through the required steps to work with the different binding modes: Add a new Silverlight child window called OwnerDetailsEdit.
In the code-behind of this window, change the default constructor—so that it accepts an instance of the Owner class—as shown in the following code: In MainPage. In the event handler, add the following code, which will create a new instance of the OwnerDetailsEdit window, passing in the created Owner instance: For the OneWay and TwoWay bindings to work, the object to which we are binding should be an instance of a class that implements the INotifyPropertyChanged interface.
In our case, we are binding an Owner instance. This instance implements the interface correctly. The following code illustrates this: Some of the data may not be updated on this screen and it will never change.
For this type of binding, the Mode can be set to OneTime. This is the case for the OwnerId field. The users should neither be able to change their ID nor should the value of this field change in the background, thereby requiring an update in the UI. The following is the XAML code for this binding: The CurrentBalance TextBlock at the bottom does not need to be editable by the user allowing a user to change his or her account balance might not be beneficial for the bank , but it does need to change when the source changes.
The final option for the Mode property is TwoWay. TwoWay bindings allow us to persist data by pushing data from the UI control to the source object. In this case, all other fields can be updated by the user. When we enter a new value, the bound Owner instance is changed. TwoWay bindings are illustrated using the following code: We've applied all the different binding modes at this point. Notice that when you change the values in the pop-up window, the details on the left of the screen are also updated.
This is because all controls are in the background bound to the same source object as shown in the following screenshot: When we looked at the basics of data binding, we saw that a binding always occurs between a source and a target. The first one is normally an in-memory object, but it can also be a UI control. The second one will always be a UI control. Normally, data flows from source to target.
However, using the Mode property, we have the option to control this. A OneTime binding should be the default for data that does not change when displayed to the user. When using this mode, the data flows from source to target. The target receives the value initially during loading and the data displayed in the target will never change. Quite logically, even if a OneTime binding is used for a TextBox, changes done to the data by the user will not flow back to the source.
IDs are a good example of using OneTime bindings. Also, when building a catalogue application, OneTime bindings can be used, as we won't change the price of the items that are displayed to the user or should we? Data will flow from source to target here also, but every change in the values of the source properties will propagate to a change of the displayed values.
Think of a stock market application where updates are happening every second. We need to push the updates to the UI of the application. The TwoWay bindings can help in persisting data. The data can now flow from source to target, and vice versa. Initially, the values of the source properties will be loaded in the properties of the controls. When we interact with these values type in a textbox, drag a slider, and so on , these updates are pushed back to the source object.
If needed, conversions can be done in both directions. There is one important requirement for the OneWay and TwoWay bindings. If we want to display up-to-date values, then the INotifyPropertyChanged interface should be implemented.
The OneTime and OneWay bindings would have the same effect, even if this interface is not implemented on the source. The TwoWay bindings would still send the updated values if the interface was not implemented; however, they wouldn't notify about the changed values.
It can be considered as a good practice to implement the interface, unless there is no chance that the updates of the data would be displayed somewhere in the application. The overhead created by the implementation is minimal.
Another option in the binding is the UpdateSourceTrigger. It allows us to specify when a TwoWay binding will push the data to the source. By default, this is determined by the control. For a TextBox, this is done on the LostFocus event; and for most other controls, it's done on the PropertyChanged event.
The value can also be set to Explicit. This means that we can manually trigger the update of the source. GetBindingExpression TextBox. TextProperty ; expression. UpdateSource ; See also Changing the values that flow between source and target can be done using converters. We'll look at these in the next chapter.
In this recipe, we'll build a small data-driven application that uses data binding. We won't manually create the data binding expressions; we'll use Blend 4 for this task. For this recipe, we'll create a small application from scratch that allows us to edit the details of a bank account owner. In order to achieve this, carry out the following steps: We'll need to open Blend 4 and go to File New Project Blend will now create a Silverlight application and a hosting website.
We'll start by adding a new class called Owner. Right-click on the Silverlight project and select Add New Item In the dialog box that appears, select the Class template and click on the OK button. The following is the code for the Owner class and it can be edited inside Blend 4: In the code-behind of MainPage. Build the solution, so that the Owner class is known to Blend and it can use the class in its dialog boxes.
Now, in the designer, add a Grid containing three TextBlock and three TextBox controls as shown in the following screenshot: We're now ready to add the data binding functionality. Select the first TextBox and in the Properties window, search for the Text property.
Instead of typing a value, click on the small square for the Advanced property options next to the text field. Select Data Binding The following screenshot shows how to access this option: In the dialog box that appears, we can now couple the Name property of the Owner type to the Text property of the TextBox.
Under the Explicit Data Context tab, mark the Use a custom path expression checkbox and enter Name as the value. Click on the down arrow so that the advanced properties are expanded and mark TwoWay as the Binding direction.
The other properties are similar as shown in the following screenshot: Let's look at the resulting XAML code for a moment. Using Expression Blend 4 for sample data generation Expression Blend 4 contains a feature that is capable of generating the sample data while developing an application. It visualizes the data on which we are working and provides us with an easier way to create an interface for a data-driven application.
This feature was added to Blend in version 3. In this recipe, we'll build a small management screen for the usage of the bank employees.
It will show an overview of the bank account owners. We wouldn't want to waste time with the creation of sample data, so we'll hand over this task to Blend. The following are the steps we need to follow for the creation of this data: Open Blend 4 and go to File New Project With MainPage. In this window, click on the Add sample data source icon and select Define New Sample Data… as shown in the following screenshot: We have the option to either embed this data source in the usercontrol This document or make it available for the entire project Project.
Select the latter option by selecting the Project radio button and clicking on the OK button. If we leave the checkbox checked, then the sample data will be used for the design time as well as the runtime. We'll keep this option enabled. Blend will now generate the data source for us. By default, a Collection is created and it contains items with two properties.
Each property has a type. Rename Property1 to Name. Now, change the type options by clicking on the Change property type icon and selecting Name as the format. The other properties are similar and are shown in the following screenshot: For the Image type, we can select a folder that contains images.
Blend will then copy these images to the SampleData subfolder inside the project. We're now ready to use the sample data—for example—in a master-detail scenario. A ListBox will contain all the Owner data from which we can select an instance. The details are shown in a Grid using some TextBlock controls. Make sure that the Data window is set to List Mode and drag the collection on to the design surface.
This will trigger the creation of a listbox in which the items are formatted, so we can see the details. Now, to view the details, we have to set the Data window to the Details Mode. Then, instead of dragging the collection, we select the properties that we want to see in the detail view and drag those onto the design surface. The result should be similar to the following screenshot: For each different type, it generated different values. Reflecting on what we learned in the previous chapter, we may start to think that data binding works as some kind of black box into which we insert the data and it just displays it.
However, this is not the case. The data binding engine gives us many points where we can extend or change this process. Advanced Data Binding The most obvious hooks we have in data binding are converters. Converters allow us to grab a value when it's coming in from a source object, perform some action on it, and then pass it to the target control. The most obvious action that we can take is formatting, though many more are possible.
We'll look at converters and their possibilities in this chapter. Data binding also allows us to perform validations. When entering data in data-bound controls such as a TextBox, it's important that we validate the data before it's sent back to the source. Silverlight 4 has quite a few options to perform this validation. We'll look at these in this chapter as well.
We can also change the way our data is being displayed using data templates. Data templates allow us to override the default behavior of controls such as a ListBox. We will build some templates in this chapter to complete the look of the Silverlight Banking application.
This chapter continues to use the same sample application, Silverlight Banking, which we have already used in the previous chapter. Hooking into the data binding process We may want to perform some additional formatting for some types of data that we want to display using data binding. Think of a date. Normally, a date is stored in the database as a combination of a date and time. However, we may only want to display the date part—perhaps formatted according to a particular culture.
Another example is a currency; the value is normally stored in the database as a double. In an application, we may want to format it by putting a dollar or a euro sign in front of it. Silverlight's data binding engine offers us a hook in the data binding process, thereby allowing us to format, change, or do whatever we want to do with the data in both directions. This is achieved through the use of a converter. Getting ready This recipe builds on the code that was created in the recipes of the previous chapter.
In this recipe, we'll build two converters. We'll start with a currency converter. This is quite basic. It will take a value and format it as a currency using the currency symbol based on the current culture. The second converter will be more advanced; it will convert from a numeric value to a color. In the sample code of the book, some more converters have been added. Carry out the following steps in order to get converters to work in a Silverlight application: We'll start by creating the currency converter.
A converter is nothing more than a class, in this sample called CurrencyConverter, which implements the IValueConverter interface. This interface defines two methods, that is, Convert and ConvertBack. Place the CurrencyConverter class in a folder called Converters within the Silverlight project. The following is the code for this class: The code in the Convert method will be applied to the data when it flows from the source to the target.
Similarly, the ConvertBack method is called when the data flows from the target to the source, so when a TwoWay binding is active. The original value is passed in the value parameter. We have access to the current culture via the culture parameter. Also, we add a "minus" sign to the string value that is returned if the value is less than zero.
Parse value. ToString ; if amount Advanced Data Binding 3. Simply creating the converter doesn't do anything. An instance of the converter has to be created and passed along with the binding using the Converter property. This is to be done in the resources collection of the XAML file in which we will be using the converter or in App.
The following code shows this instantiation in App. Note that we also need to add the namespace mapping. After that, we specify this converter as the value for the Converter property in the Binding declaration. While this simple converter converts a double into a string, more advanced conversions can be performed.
What if, for example, we want to color negative amounts red and positive amounts green? The Convert method looks quite similar, except that it now returns a SolidColorBrush. Green ; else return new SolidColorBrush Colors.