Sie sind auf Seite 1von 419

Resource Links for 70-513 WCF Certification Exam

1
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Creating Services (20%)
Create service and operation contracts. This objective may include but is not limited to: one-way,
duplex, and request reply; creating and specifying fault contracts; configuration-based contracts;
exposing service metadata; selecting serialization (e.g., data contract serializer vs. XML
serializer)This objective does not include: designing service and operation contracts;
transactions, instantiation, security-related attributes
Designing Service Contracts
This topic describes what service contracts are, how they are defined, what operations are
available (and the implications for the underlying message exchanges), what data types are used,
and other issues that help you design operations that properly satisfy the requirements of your
scenario.
Creating a Service Contract
Services are groups of operations. To create a service contract you must model operations and
specify their grouping. In Windows Communication Foundation (WCF) applications, define the
operations by creating a method and marking it with the OperationContractAttribute attribute.
Then, to create a service contract, group together your operations, either by declaring them
within an interface marked with the ServiceContractAttribute attribute, or by defining them in a
class marked with the same attribute. (For a basic example, see How to: Define a Windows
Communication Foundation Service Contract.)
Any methods that do not have a OperationContractAttribute attribute are not service
operations and are not exposed for use by clients of WCF services. Like any managed method,
they can only be called by objects within their declared access scope.
In a similar manner, it is also valid to create a service contract class or interface that declares no
service operationsthe effect is the same as a class or interface with no methods. Any services
built using a contract of this type expose no operations for clients to use. This topic describes the
following decision points when designing a service contract:
Whether to use classes or interfaces.
How to specify the data types you want to exchange.
The types of exchange patterns you can use.
Resource Links for 70-513 WCF Certification Exam
2
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Whether you can make explicit security requirements part of the contract.
The restrictions for operation inputs and outputs.
Classes or Interfaces
Both classes and interfaces represent a grouping of functionality and, therefore, both can be used
to define a WCF service contract. However, it is recommended that you use interfaces because
they directly model service contracts. Without an implementation, interfaces do no more than
define a grouping of methods with certain signatures. Likewise, a service contract without an
implementation defines a grouping of operations with certain signatures. Implement a service
contract interface and you have implemented a WCF service.
All the benefits of managed interfaces apply to service contract interfaces:
Service contract interfaces can extend any number of other service contract interfaces.
A single class can implement any number of service contracts by implementing those service contract
interfaces.
You can modify the implementation of a service contract by changing the interface implementation, while
the service contract remains the same.
You can version your service by implementing the old interface and the new one. Old clients connect to
the original version, while newer clients can connect to the newer version.
Note:
When inheriting from other service contract interfaces, you cannot override operation properties, such as
the name or namespace. If you attempt to do so, you create a new operation in the current service
contract.
For an example of using an interface to create a service contract, see How to: Create a Service
with a Contract Interface.
You can, however, use a class to define a service contract and implement that contract at the
same time. The advantage of creating your services by applying ServiceContractAttribute and
OperationContractAttribute directly to the class and the methods on the class, respectively, is
speed and simplicity. The disadvantages are that managed classes do not support multiple
inheritance, and as a result they can only implement one service contract at a time. In addition,
any modification to the class or method signatures modifies the public contract for that service,
which can prevent unmodified clients from using your service. For more information, see
Implementing Service Contracts.
Resource Links for 70-513 WCF Certification Exam
3
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
For an example that uses a class to create a service contract and implements it at the same time,
see How to: Create a Windows Communication Foundation Contract with a Class.
At this point, you should understand the difference between defining your service contract by
using an interface and by using a class. The next step is deciding what data can be passed back
and forth between a service and its clients.
Parameters and Return Values
Each operation has a return value and a parameter, even if these are void. However, unlike a
local method, in which you can pass references to objects from one object to another, service
operations do not pass references to objects. Instead, they pass copies of the objects.
This is significant because each type used in a parameter or return value must be serializable;
that is, it must be possible to convert an object of that type into a stream of bytes and from a
stream of bytes into an object.Primitive types are serializable by default, as are many types in the
.NET Framework.
Note:
The value of the parameter names in the operation signature are part of the contract and are case sensitive.
If you want to use the same parameter name locally but modify the name in the published metadata, see
the System.ServiceModel.MessageParameterAttribute.
Data Contracts
Service-oriented applications like Windows Communication Foundation (WCF) applications are
designed to interoperate with the widest possible number of client applications on both Microsoft
and non-Microsoft platforms. For the widest possible interoperability, it is recommended that
you mark your types with the DataContractAttribute and DataMemberAttribute attributes to
create a data contract, which is the portion of the service contract that describes the data that your
service operations exchange.
Data contracts are opt-in style contracts: No type or data member is serialized unless you
explicitly apply the data contract attribute. Data contracts are unrelated to the access scope of the
managed code: Private data members can be serialized and sent elsewhere to be accessed
publicly. (For a basic example of a data contract, see How to: Create a Basic Data Contract for a
Class or Structure.) WCF handles the definition of the underlying SOAP messages that enable
the operation's functionality as well as the serialization of your data types into and out of the
Resource Links for 70-513 WCF Certification Exam
4
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
body of the messages. As long as your data types are serializable, you do not need to think about
the underlying message exchange infrastructure when designing your operations.
Although the typical WCF application uses the DataContractAttribute and
DataMemberAttribute attributes to create data contracts for operations, you can use other
serialization mechanisms. The standard ISerializable, SerializableAttribute and IXmlSerializable
mechanisms all work to handle the serialization of your data types into the underlying SOAP
messages that carry them from one application to another. You can employ more serialization
strategies if your data types require special support. For more information about the choices for
serialization of data types in WCF applications, see Specifying Data Transfer in Service
Contracts.It is important to note that the CLR names in the definition of a Service Contract and
its operations are significant and should not be confused. To avoid confusion of types used to
define a Service Contract use the ObfuscationAttribute and ObfuscateAssemblyAttribute
attributes.
Mapping Parameters and Return Values to Message Exchanges
Service operations are supported by an underlying exchange of SOAP messages that transfer
application data back and forth, in addition to the data required by the application to support
certain standard security, transaction, and session-related features. Because this is the case, the
signature of a service operation dictates a certain underlying message exchange pattern (MEP)
that can support the data transfer and the features an operation requires. You can specify three
patterns in the WCF programming model: request/reply, one-way, and duplex message patterns.
Request/Reply
A request/reply pattern is one in which a request sender (a client application) receives a reply
with which the request is correlated. This is the default MEP because it supports both an
operation in which one or more parameters are passed to the operation and a return and one or
more out values that the operation passes back to the caller. For example, the following C# code
example shows a basic service operation that takes one string and returns a string.
C#
[OperationContractAttribute]
string Hello(string greeting);
The following is the equivalent Visual Basic code.
VB
Resource Links for 70-513 WCF Certification Exam
5
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<OperationContractAttribute()>
Function Hello (ByVal greeting AsString) AsString
This operation signature dictates the form of underlying message exchange. If no correlation
existed, WCF cannot determine for which operation the return value is intended.
Note that unless you specify a different underlying message pattern, even service operations that
return void (Nothing in Visual Basic) are request/reply message exchanges. The result for your
operation is that unless a client invokes the operation asynchronously, the client stops processing
until the return message is received, even though that message is empty in the normal case. The
following C# code example shows an operation that does not return until the client has received
an empty message in response.
C#
[OperationContractAttribute]
void Hello(string greeting);
The following is the equivalent Visual Basic code.
VB
<OperationContractAttribute()>
Sub Hello (ByVal greeting AsString)
The preceding example can slow client performance and responsiveness if the operation takes a
long time to perform, but there are advantages to request/reply operations even when they return
void. The most obvious one is that SOAP faults can be returned in the response message, which
indicates that some service-related error condition has occurred, whether in communication or
processing. SOAP faults that are specified in a service contract are passed to the client
application as a FaultException object, where the type parameter is the type specified in the
service contract. This makes notifying clients about error conditions in WCF services easy. For
more information about exceptions, SOAP faults, and error handling, see Specifying and
Handling Faults in Contracts and Services. To see an example of a request/reply service and
client, see How to: Create a Request-Reply Contract. For more information about issues with the
request-reply pattern, see Request-Reply Services.
One-way
If the client of a WCF service application should not wait for the operation to complete and does
not process SOAP faults, the operation can specify a one-way message pattern. A one-way
operation is one in which a client invokes an operation and continues processing after WCF
Resource Links for 70-513 WCF Certification Exam
6
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
writes the message to the network. Typically this means that unless the data being sent in the
outbound message is extremely large the client continues running almost immediately (unless
there is an error sending the data). This type of message exchange pattern supports event-like
behavior from a client to a service application.
A message exchange in which one message is sent and none are received cannot support a
service operation that specifies a return value other than void; in this case an
InvalidOperationException exception is thrown.
No return message also means that there can be no SOAP fault returned to indicate any errors in
processing or communication. (Communicating error information when operations are one-way
operations requires a duplex message exchange pattern.)
To specify a one-way message exchange for an operation that returns void, set the IsOneWay
property to true, as in the following C# code example.
C#
[OperationContractAttribute(IsOneWay=true)]
void Hello(string greeting);
The following is the equivalent Visual Basic code.
VB
<OperationContractAttribute(IsOneWay := True)>
Sub Hello (ByVal greeting AsString)
This method is identical to the preceding request/reply example, but setting the IsOneWay
property to true means that although the method is identical, the service operation does not send
a return message and clients return immediately once the outbound message has been handed to
the channel layer. For an example, see How to: Create a One-Way Contract. For more
information about the one-way pattern, see One-Way Services.
Duplex
A duplex pattern is characterized by the ability of both the service and the client to send
messages to each other independently whether using one-way or request/reply messaging. This
form of two-way communication is useful for services that must communicate directly to the
client or for providing an asynchronous experience to either side of a message exchange,
including event-like behavior.
The duplex pattern is slightly more complex than the request/reply or one-way patterns because
of the additional mechanism for communicating with the client.
Resource Links for 70-513 WCF Certification Exam
7
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
To design a duplex contract, you must also design a callback contract and assign the type of that
callback contract to the CallbackContract property of the ServiceContractAttribute attribute
that marks your service contract.
To implement a duplex pattern, you must create a second interface that contains the method
declarations that are called on the client.
For an example of creating a service, and a client that accesses that service, see How to: Create a
Duplex Contract and How to: Access Services with a Duplex Contract. For a working sample,
see Service Contract: Duplex. For more information about issues using duplex contracts, see
Duplex Services.
Caution:
When a service receives a duplex message, it looks at the ReplyTo element in that incoming message to
determine where to send the reply. If the channel that is used to receive the message is not secured, then
an untrusted client could send a malicious message with a target machine's ReplyTo, leading to a denial
of service (DOS) of that target machine.
Out and Ref Parameters
In most cases, you can use in parameters (ByVal in Visual Basic) and out and ref parameters
(ByRef in Visual Basic). Because both out and ref parameters indicate that data is returned from
an operation, an operation signature such as the following specifies that a request/reply operation
is required even though the operation signature returns void.
C#
[ServiceContractAttribute]
publicinterface IMyContract
{
[OperationContractAttribute]
publicvoid PopulateData(ref CustomDataType data);
}
The following is the equivalent Visual Basic code.
[Visual Basic]
<ServiceContractAttribute()> _
Public Interface IMyContract
<OperationContractAttribute()> _
Public Sub PopulateData(ByRef data As CustomDataType)
Resource Links for 70-513 WCF Certification Exam
8
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
End Interface
The only exceptions are those cases in which your signature has a particular structure. For
example, you can use the NetMsmqBinding binding to communicate with clients only if the
method used to declare an operation returns void; there can be no output value, whether it is a
return value, ref, or out parameter.In addition, using out or ref parameters requires that the
operation have an underlying response message to carry back the modified object. If your
operation is a one-way operation, an InvalidOperationException exception is thrown at
runtime.
Specify Message Protection Level on the Contract
When designing your contract, you must also decide the message protection level of services that
implement your contract. This is necessary only if message security is applied to the binding in
the contract's endpoint. If the binding has security turned off (that is, if the system-provided
binding sets the System.ServiceModel.SecurityMode to the value
System.ServiceModel.SecurityMode.None) then you do not have to decide on the message
protection level for the contract. In most cases, system-provided bindings with message-level
security applied provide a sufficient protection level and you do not have to consider the
protection level for each operation or for each message.The protection level is a value that
specifies whether the messages (or message parts) that support a service are signed, signed and
encrypted, or sent without signatures or encryption. The protection level can be set at various
scopes: At the service level, for a particular operation, for a message within that operation, or a
message part. Values set at one scope become the default value for smaller scopes unless
explicitly overridden. If a binding configuration cannot provide the required minimum protection
level for the contract, an exception is thrown. And when no protection level values are explicitly
set on the contract, the binding configuration controls the protection level for all messages if the
binding has message security. This is the default behavior.
Note:
Deciding whether to explicitly set various scopes of a contract to less than the full protection level of
System.Net.Security.ProtectionLevel.EncryptAndSign is generally a decision that trades some degree of
security for increased performance. In these cases, your decisions must revolve around your operations
and the value of the data they exchange. For more information, see Securing Services.
Resource Links for 70-513 WCF Certification Exam
9
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
For example, the following code example does not set either the ProtectionLevel or the
ProtectionLevel property on the contract.
C#
[ServiceContract]
publicinterface ISampleService
{
[OperationContractAttribute]
publicstring GetString();
[OperationContractAttribute]
publicint GetInt();
}
The following is the equivalent Visual Basic code.
[Visual Basic]
<ServiceContractAttribute()> _
Public Interface ISampleService
<OperationContractAttribute()> _
Public Function GetString()As String
<OperationContractAttribute()> _
Public Function GetData() As Integer
End Interface

When interacting with an ISampleService implementation in an endpoint with a default
WSHttpBinding (the default System.ServiceModel.SecurityMode, which is Message), all
messages are encrypted and signed because this is the default protection level. However, when
an ISampleService service is used with a default BasicHttpBinding (the default SecurityMode,
which is None), all messages are sent as text because there is no security for this binding and so
the protection level is ignored (that is, the messages are neither encrypted nor signed). If the
SecurityMode was changed to Message, then these messages would be encrypted and signed
(because that would now be the binding's default protection level).If you want to explicitly
specify or adjust the protection requirements for your contract, set the ProtectionLevel property
(or any of the ProtectionLevel properties at a smaller scope) to the level your service contract
requires. In this case, using an explicit setting requires the binding to support that setting at a
Resource Links for 70-513 WCF Certification Exam
10
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
minimum for the scope used. For example, the following code example specifies one
ProtectionLevel value explicitly, for the GetGuid operation.
[C#]
[ServiceContract]
public interface IExplicitProtectionLevelSampleService
{
[OperationContractAttribute]
public string GetString();
[OperationContractAttribute(ProtectionLevel=ProtectionLevel.None)]
public int GetInt();
[OperationContractAttribute(ProtectionLevel=ProtectionLevel.EncryptAndSign)]
public int GetGuid();
}
The following is the equivalent Visual Basic code.
[Visual Basic]
<ServiceContract()> _
Public Interface IExplicitProtectionLevelSampleService
<OperationContract()> _
Public Function GetString() As String
End Function
<OperationContract(ProtectionLevel := ProtectionLevel.None)> _
Public Function GetInt() As Integer
End Function
<OperationContractAttribute(ProtectionLevel := ProtectionLevel.EncryptAndSign)> _
Public Function GetGuid() As Integer
End Function
End Interface

A service that implements this IExplicitProtectionLevelSampleService contract and has an endpoint
that uses the default WSHttpBinding (the default System.ServiceModel.SecurityMode, which
is Message) has the following behavior:
The GetString operation messages are encrypted and signed.
The GetInt operation messages are sent as unencrypted and unsigned (that is, plain) text.
The GetGuid operation System.Guid is returned in a message that is encrypted and signed.
Resource Links for 70-513 WCF Certification Exam
11
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
For more information about protection levels and how to use them, see Understanding Protection
Level. For more information about security, see Securing Services.
Other Operation Signature Requirements
Some application features require a particular kind of operation signature. For example, the
NetMsmqBinding binding supports durable services and clients, in which an application can
restart in the middle of communication and pick up where it left off without missing any
messages. (For more information, see Queues in Windows Communication Foundation.)
However, durable operations must take only one in parameter and have no return value.
Another example is the use of Stream types in operations. Because the Stream parameter
includes the entire message body, if an input or an output (that is, ref parameter, out parameter,
or return value) is of type Stream, then it must be the only input or output specified in your
operation. In addition, the parameter or return type must be either Stream,
System.ServiceModel.Channels.Message, or System.Xml.Serialization.IXmlSerializable. For
more information about streams, see Large Data and Streaming.
Names, Namespaces, and Obfuscation
The names and namespaces of the .NET types in the definition of contracts and operations are
significant when contracts are converted into WSDL and when contract messages are created and
sent. Therefore, it is strongly recommended that service contract names and namespaces are
explicitly set using the Name and Namespace properties of all supporting contract attributes
such as the ServiceContractAttribute, OperationContractAttribute, DataContractAttribute,
DataMemberAttribute, and other contract attributes.
One result of this is that if the names and namespaces are not explicitly set, the use of IL
obfuscation on the assembly alters the contract type names and namespaces and results in
modified WSDL and wire exchanges that typically fail. If you do not set the contract names and
namespaces explicitly but do intend to use obfuscation, use the ObfuscationAttribute and
ObfuscateAssemblyAttribute attributes to prevent the modification of the contract type names
and namespaces.
Specifying and Handling Faults in Contracts
and Services
Resource Links for 70-513 WCF Certification Exam
12
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Windows Communication Foundation (WCF) applications handle error situations by mapping
managed exception objects to SOAP fault objects and SOAP fault objects to managed exception
objects. The topics in this section discuss how to design contracts to expose error conditions as
custom SOAP faults, how to return such faults as part of service implementation, and how clients
catch such faults.
Error Handling Overview
In all managed applications, processing errors are represented by Exception objects. In SOAP-
based applications such as WCF applications, service methods communicate processing error
information using SOAP fault messages. SOAP faults are message types that are included in the
metadata for a service operation and therefore create a fault contract that clients can use to make
their operation more robust or interactive. In addition, because SOAP faults are expressed to
clients in XML form, it is a highly interoperable type system that clients on any SOAP platform
can use, increasing the reach of your WCF application.
Because WCF applications run under both types of error systems, any managed exception
information that is sent to the client must be converted from exceptions into SOAP faults on the
service, sent, and converted from SOAP faults to fault exceptions in WCF clients. In the case of
duplex clients, client contracts can also send SOAP faults back to a service. In either case, you
can use the default service exception behaviors, or you can explicitly control whetherand
howexceptions are mapped to fault messages.
Two types of SOAP faults can be sent: declared and undeclared. Declared SOAP faults are those
in which an operation has a System.ServiceModel.FaultContractAttribute attribute that specifies
a custom SOAP fault type. Undeclared SOAP faults are not specified in the contract for an
operation.
It is strongly recommended that service operations declare their faults by using the
FaultContractAttribute attribute to formally specify all SOAP faults that a client can expect to
receive in the normal course of an operation. It is also recommended that you return in a SOAP
fault only the information that a client must know to minimize information disclosure.
Typically, services (and duplex clients) take the following steps to successfully integrate error
handling into their applications:
Map exception conditions to custom SOAP faults.
Clients and services send and receive SOAP faults as exceptions.
Resource Links for 70-513 WCF Certification Exam
13
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
In addition, WCF clients and services can use undeclared soap faults for debugging purposes and
can extend the default error behavior. The following sections discuss these tasks and concepts.
Map Exceptions to SOAP Faults
The first step in creating an operation that handles error conditions is to decide under what
conditions a client application should be informed about errors. Some operations have error
conditions specific to their functionality. For example, a PurchaseOrder operation might return
specific information to customers who are no longer permitted to initiate a purchase order. In
other cases, such as a Calculator service, a more general MathFault SOAP fault may be able to
describe all error conditions across an entire service. Once the error conditions of clients of your
service are identified, a custom SOAP fault can be constructed and the operation can be marked
as returning that SOAP fault when its corresponding error condition arises.
For more information about this step of developing your service or client, see Defining and
Specifying Faults.Clients and Services Handle SOAP Faults as ExceptionsIdentifying operation
error conditions, defining custom SOAP faults, and marking those operations as returning those
faults are the first steps in successful error handling in WCF applications. The next step is to
properly implement the sending and receiving of these faults. Typically services send faults to
inform client applications about error conditions, but duplex clients can also send SOAP faults to
services. For more information, see Sending and Receiving Faults.Undeclared SOAP Faults and
DebuggingDeclared SOAP faults are extremely useful for building robust, interoperable,
distributed applications. However, in some cases it is useful for a service (or duplex client) to
send an undeclared SOAP fault, one that is not mentioned in the Web Services Description
Language (WSDL) for that operation. For example, when developing a service, unexpected
situations can occur in which it is useful for debugging purposes to send information back to the
client. In addition, you can set the ServiceBehaviorAttribute.IncludeExceptionDetailInFaults
property or the ServiceDebugBehavior.IncludeExceptionDetailInFaults property to true to permit
WCF clients to obtain information about internal service operation exceptions. Both sending
individual faults and setting the debugging behavior properties are described in Sending and
Receiving Faults.
Important
Because managed exceptions can expose internal application information, setting
Resource Links for 70-513 WCF Certification Exam
14
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
ServiceBehaviorAttribute.IncludeExceptionDetailInFaults or
ServiceDebugBehavior.IncludeExceptionDetailInFaults to true can permit WCF clients to obtain
information about internal service operation exceptions, including personally identifiable or
other sensitive information.
Therefore, setting ServiceBehaviorAttribute.IncludeExceptionDetailInFaults or
ServiceDebugBehavior.IncludeExceptionDetailInFaults to true is recommended only as a way to
temporarily debug a service application. In addition, the WSDL for a method that returns
unhandled managed exceptions in this way does not contain the contract for the
FaultException<TDetail> of type ExceptionDetail. Clients must expect the possibility of an
unknown SOAP fault (returned to WCF clients as System.ServiceModel.FaultException objects)
to obtain the debugging information properly.
Customizing Error Handling with IErrorHandlerIf you have special requirements to either customize the
response message to the client when an application-level exception happens or perform some custom
processing after the response message is returned, implement the
System.ServiceModel.Dispatcher.IErrorHandler interface. Fault Serialization IssuesWhen deserializing a
fault contract, WCF first attempts to match the fault contract name in the SOAP message with the fault
contract type. If it cannot find an exact match it will then search the list of available fault contracts in
alphabetical order for a compatible type. If two fault contracts are compatible types (one is a subclass of
another, for example) the wrong type may be used to de-serialize the fault. This only occurs if the fault
contract does not specify a name, namespace, and action. To prevent this issue from occurring, always
fully qualify fault contracts by specifying the name, namespace, and action attributes. Additionally if you
have defined a number of related fault contracts derived from a shared base class, make sure to mark any
new members with [DataMember(IsRequired=true)]. For more information on this IsRequired attribute
see, DataMemberAttribute. This will prevent a base class from being a compatible type and force the fault
to be deserialized into the correct derived type.
Metadata
The Windows Communication Foundation (WCF) provides an infrastructure for exporting,
publishing, retrieving, and importing service metadata. WCF services use metadata to describe
how to interact with the service's endpoints so that tools, such as Svcutil.exe, can automatically
generate client code for accessing the service.
Resource Links for 70-513 WCF Certification Exam
15
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
In This Section
Metadata Architecture Overview
A high-level overview of metadata architecture.
Metadata Formats
Describes the different metadata formats.
Exporting and Importing Metadata
Describes how to export and import metadata.
Publishing Metadata
Describes how WCF publishes metadata.
Retrieving Metadata
Describes the different ways to retrieve metadata.
Using Metadata
Describes different ways to use service metadata.
Security Considerations with Metadata
Describes important security considerations when dealing with service metadata.
Metadata Architecture Overview
Windows Communication Foundation (WCF) provides a rich infrastructure for exporting,
publishing, retrieving, and importing service metadata. WCF services use metadata to describe
how to interact with the service's endpoints so that tools, such as Svcutil.exe, can automatically
generate client code for accessing the service.Most of the types that make up the WCF metadata
infrastructure reside in the System.ServiceModel.Description namespace. WCF uses the
ServiceEndpoint class to describe endpoints in a service. You can use WCF to generate metadata
for service endpoints or import service metadata to generate ServiceEndpoint instances.
WCF represents the metadata for a service as an instance of the MetadataSet type, the structure
of which is strongly tied to the metadata serialization format defined in WS-MetadataExchange.
The MetadataSet type bundles the actual service metadata, such as Web Services Description
Language (WSDL) documents, XML schema documents, or WS-Policy expressions, as a
collection of MetadataSection instances. Each
System.ServiceModel.Description.MetadataSection instance contains a specific metadata
Resource Links for 70-513 WCF Certification Exam
16
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
dialect and an identifier. A System.ServiceModel.Description.MetadataSection can contain
the following items in its System.ServiceModel.Description.MetadataSection.Metadata property:
Raw metadata.
A MetadataReference instance.
A MetadataLocation instance.
A System.ServiceModel.Description.MetadataReference instances point to another metadata
exchange (MEX) endpoint and System.ServiceModel.Description.MetadataLocation instances
point to a metadata document using an HTTP URL. WCF supports using WSDL documents to
describe service endpoints, service contracts, bindings, message exchange patterns, messages and
fault messages implemented by a service. Data types used by the service are described in WSDL
documents using XML schema. For more information, see Schema Import and Export. You can
use WCF to export and import WSDL extensions for service behavior, contract behaviors, and
binding elements that extend the functionality of a service. For more information, see Exporting
Custom Metadata for a WCF Extension.
Exporting Service Metadata
In WCF, metadata export is the process of describing service endpoints and projecting them into
a parallel, standardized representation that clients can use to understand how to use the service.
To export metadata from ServiceEndpoint instances, use an implementation of the
MetadataExporter abstract class. A System.ServiceModel.Description.MetadataExporter
implementation generates metadata that is encapsulated in a MetadataSet instance.
The System.ServiceModel.Description.MetadataExporter class provides a framework for
generating policy expressions that describe the capabilities and requirements of an endpoint
binding and its associated operations, messages, and faults. These policy expressions are
captured in a PolicyConversionContext instance. A
System.ServiceModel.Description.MetadataExporter implementation can then attach these
policy expressions to the metadata it generates.The
System.ServiceModel.Description.MetadataExporter calls into each
System.ServiceModel.Channels.BindingElement that implements the IPolicyExportExtension
interface in the binding of a ServiceEndpoint when generating a PolicyConversionContext
object for the System.ServiceModel.Description.MetadataExporter implementation to use.
Resource Links for 70-513 WCF Certification Exam
17
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
You can export new policy assertions by implementing the IPolicyExportExtension interface
on your custom implementations of the BindingElement type. The WsdlExporter type is the
implementation of the System.ServiceModel.Description.MetadataExporter abstract class
included with WCF. The WsdlExporter type generates WSDL metadata with attached policy
expressions. To export custom WSDL metadata or WSDL extensions for endpoint behaviors,
contract behaviors, or binding elements in a service endpoint, you can implement the
IWsdlExportExtension interface. The WsdlExporter looks at a ServiceEndpoint instance for
binding elements, operation behaviors, contract behaviors, and endpoint behaviors that
implement the IWsdlExportExtension interface when generating the WSDL document.
Publishing Service Metadata
WCF services publish metadata by exposing one or more metadata endpoints. Publishing service
metadata makes service metadata available using standardized protocols, such as MEX and
HTTP/GET requests. Metadata endpoints are similar to other service endpoints in that they have
an address, a binding, and a contract. You can add metadata endpoints to a service host in
configuration or in code. To publish metadata endpoints for a WCF service, you must first add an
instance of the ServiceMetadataBehavior service behavior to the service. Adding a
System.ServiceModel.Description.ServiceMetadataBehavior instance to your service
augments your service with the ability to publish metadata by exposing one or more metadata
endpoints. Once you add the System.ServiceModel.Description.ServiceMetadataBehavior
service behavior you can then expose metadata endpoints that support the MEX protocol or
metadata endpoints that respond to HTTP/GET requests. To add metadata endpoints that use the
MEX protocol, add service endpoints to your service host that use the service contract named
IMetadataExchange.WCF defines the IMetadataExchange interface that has this service contract
name. WS-MetadataExchange endpoints, or MEX endpoints, can use one of the four default
bindings exposed by the static factory methods on the MetadataExchangeBindings class to match
the default bindings used by WCF tools, such as Svcutil.exe. You can also configure MEX
metadata endpoints using a custom binding.The ServiceMetadataBehavior uses a
System.ServiceModel.Description.WsdlExporter to export metadata for all service endpoints
in your service. For more information about exporting metadata from a service, see Exporting
and Importing Metadata.The ServiceMetadataBehavior augments your service host by adding a
Resource Links for 70-513 WCF Certification Exam
18
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
ServiceMetadataExtension instance as an extension to your service host. The
System.ServiceModel.Description.ServiceMetadataExtension provides the implementation
for the metadata publishing protocols. You can also use the
System.ServiceModel.Description.ServiceMetadataExtension to get the service's metadata at
runtime by accessing the Metadata property.
Caution:
If you add a MEX endpoint in your application configuration file and then attempt to add the
ServiceMetadataBehavior to your service host in code you get the following exception:
System.InvalidOperationException: The contract name 'IMetadataExchange' could not be found in the list
of contracts implemented by the service Service1. Add a ServiceMetadataBehavior to the configuration
file or to the ServiceHost directly to enable support for this contract.
You can work around this issue by either adding the ServiceMetadataBehavior in the configuration file
or adding both the endpoint and ServiceMetadataBehavior in code.
For an example of adding ServiceMetadataBehavior in an application configuration file, see the Getting
Started Sample. For an example of adding ServiceMetadataBehavior in code, see the Self-Host sample.
Caution:
When publishing metadata for a service that exposes two different service contracts in which each contain
an operation of the same name an exception is thrown. For example, if you have a service that exposes a
service contract called ICarService that has an operation Get(Car c) and the same service exposes a
service contract called IBookService that has an operation Get(Book b), an exception is thrown or an
error message is displayed when generating the service's metadata. To work around this issue do one of
the following:
Rename one of the operations.
Set the Name to a different name.
Set one of the operations' namespaces to a different namespace using the Namespace property.
Retrieving Service Metadata
WCF can retrieve service metadata using standardized protocols such as WS-MetadataExchange
and HTTP. Both of these protocols are supported by the MetadataExchangeClient type. You
retrieve service metadata using the
System.ServiceModel.Description.MetadataExchangeClient type by providing an address and
an optional binding. The binding used by a
Resource Links for 70-513 WCF Certification Exam
19
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
System.ServiceModel.Description.MetadataExchangeClient instance can be one of the
default bindings from the MetadataExchangeBindings static class, a user-supplied binding, or a
binding loaded from an endpoint configuration for the IMetadataExchange contract. The
System.ServiceModel.Description.MetadataExchangeClient can also resolve HTTP URL
references to metadata using the HttpWebRequest type.By default, a
System.ServiceModel.Description.MetadataExchangeClient instance is tied to a single
ChannelFactoryBase instance. You can change or replace the ChannelFactoryBase instance
used by a System.ServiceModel.Description.MetadataExchangeClient by overriding the
GetChannelFactory virtual method. Similarly, you can change or replace the
System.Net.HttpWebRequest instance used by a
System.ServiceModel.Description.MetadataExchangeClient to make HTTP/GET requests by
overriding the
System.ServiceModel.Description.MetadataExchangeClient.GetWebRequest(System.Uri,System
.String,System.String) virtual method.You can retrieve service metadata using WS-
MetadataExchange or HTTP/GET requests by using the Svcutil.exe tool and passing the
/target:metadata switch and an address. Svcutil.exe downloads the metadata at the specified
address and saves the files to disk. Svcutil.exe uses a
System.ServiceModel.Description.MetadataExchangeClient instance internally and loads an
MEX endpoint configuration (from the application configuration file) whose name matches the
scheme of the address passed to Svcutil.exe, if one exists. Otherwise, Svcutil.exe defaults to
using one of the bindings defined by the MetadataExchangeBindings static factory type.
Importing Service Metadata
In WCF, metadata import is the process of generating an abstract representation of a service or
its component parts from its metadata. For example, WCF can import ServiceEndpoint
instances, Binding instances or ContractDescription instances from a WSDL document for a
service. To import service metadata in WCF, use an implementation of the MetadataImporter
abstract class. Types that derive from the
System.ServiceModel.Description.MetadataImporter class implement support for importing
metadata formats that take advantage of the WS-Policy import logic in WCF.
Resource Links for 70-513 WCF Certification Exam
20
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
A System.ServiceModel.Description.MetadataImporter implementation collects the policy
expressions attached to the service metadata in a PolicyConversionContext object. The
System.ServiceModel.Description.MetadataImporter then processes the policies as part of
importing the metadata by calling the implementations of the IPolicyImportExtension interface
in the PolicyImportExtensions property.
You can add support for importing new policy assertions to a
System.ServiceModel.Description.MetadataImporter by adding your own implementation of
the IPolicyImportExtension interface to the PolicyImportExtensions collection on a
System.ServiceModel.Description.MetadataImporter instance. Alternatively, you can register
your policy import extension in your client application configuration file.
The System.ServiceModel.Description.WsdlImporter type is the implementation of the
System.ServiceModel.Description.MetadataImporter abstract class included with WCF. The
System.ServiceModel.Description.WsdlImporter type imports WSDL metadata with attached
policies that are bundled in a MetadataSet object.
You can add support for importing WSDL extensions by implementing the
IWsdlImportExtension interface and then adding your implementation to the
WsdlImportExtensions property on your System.ServiceModel.Description.WsdlImporter
instance. The System.ServiceModel.Description.WsdlImporter can also load implementations
of the System.ServiceModel.Description.IWsdlImportExtension interface registered in your
client application configuration file.
Dynamic Bindings
You can dynamically update the binding that you use to create a channel to a service endpoint in
the event that the binding for the endpoint changes or you want to create a channel to an endpoint
that uses the same contract but has a different binding. You can use the MetadataResolver static
class to retrieve and import metadata at runtime for service endpoints that implement a specific
contract. You can then use the imported System.ServiceModel.Description.ServiceEndpoint
objects to create a client or channel factory to the desired endpoint.
Metadata Formats
Resource Links for 70-513 WCF Certification Exam
21
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Windows Communication Foundation (WCF) supports the metadata formats in the following
table.
Metadata Specifications and Usage
Protocol Specification and usage
WSDL 1.1
Web Services Description Language (WSDL) 1.1
WCF uses Web Services Description Language (WSDL) to describe
services.
XML Schema
XML Schema Part 2: Datatypes Second Edition and XML Schema Part
1: Structures Second Edition
WCF uses the XML Schema to describe data types used in messages.
WS Policy
Web Services Policy 1.2 - Framework (WS-Policy)
Web Services Policy 1.5 - Framework
WCF uses the WS-Policy 1.2 or 1.5 specifications with domain-specific
assertions to describe service requirements and capabilities.
WS Policy
Attachments
Web Services Policy 1.2 - Attachment (WS-PolicyAttachment)
WCF implements WS-Policy Attachments to attach policy expressions
at various scopes in WSDL.
WS Metadata
Exchange
Web Services Metadata Exchange (WS-MetadataExchange) version 1.1
WCF implements WS-MetadataExchange to retrieve XML Schema,
WSDL, and WS-Policy.
WS Addressing
Binding for WSDL
Web Services Addressing 1.0 - WSDL Binding
WCF implements WS-Addressing Binding for WSDL to attach
addressing information in WSDL.
Exporting and Importing Metadata
In Windows Communication Foundation (WCF), exporting metadata is the process of describing
service endpoints and projecting them into a parallel, standardized representation that clients can
use to understand how to use the service. Importing service metadata is the process of generating
ServiceEndpoint instances or parts from service metadata.
Resource Links for 70-513 WCF Certification Exam
22
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Exporting Metadata
To export metadata from System.ServiceModel.Description.ServiceEndpoint instances, use an
implementation of the MetadataExporter abstract class. The WsdlExporter type is the
implementation of the MetadataExporter abstract class included with WCF.
The System.ServiceModel.Description.WsdlExporter type generates Web Services
Description Language (WSDL) metadata with attached policy expressions encapsulated in a
MetadataSet instance. You can use a System.ServiceModel.Description.WsdlExporter
instance to iteratively export metadata for ContractDescription objects and ServiceEndpoint
objects. You can also export a collection of ServiceEndpoint objects and associate them with a
specific service name.
Note:
You can only use the WsdlExporter to export metadata from ContractDescription instances
that contain common language runtime (CLR) type information, such as a ContractDescription
instance created using the ContractDescription.GetContract method or created as part of the
ServiceDescription for a ServiceHost instance. You cannot use the WsdlExporter to export
metadata from ContractDescription instances imported from service metadata or constructed
without type information.
Importing Metadata
Importing WSDL Documents
To import service metadata in WCF, use an implementation of the MetadataImporter abstract
class. The System.ServiceModel.Description.WsdlImporter type is the implementation of the
MetadataImporter abstract class included with WCF. The WsdlImporter type imports WSDL
metadata with attached policies bundled in a MetadataSet object.
The WsdlImporter type gives you control over how to import the metadata. You can import all
of the endpoints, all of the bindings, or all of the contracts. You can import all of the endpoints
associated with a specific WSDL service, binding, or port type. You can also import the endpoint
for a specific WSDL port, the binding for a specific WSDL binding or the contract for a specific
WSDL port type.
Resource Links for 70-513 WCF Certification Exam
23
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The WsdlImporter also exposes a KnownContracts property that allows you to specify a set of
contracts that do not need to be imported. The WsdlImporter uses the contracts in the
KnownContracts property instead of importing a contract with the same qualified name from
the metadata.
Importing Policies
The WsdlImporter type collects the policy expressions attached to the message, operation, and
endpoint policy subjects and then uses the IPolicyImportExtension implementations in the
PolicyImportExtensions collection to import the policy expressions.The policy import logic
automatically handles policy references to policy expressions in the same WSDL document and
is identified with a wsu:Id or xml:id attribute. The policy import logic protects applications
against circular policy references by limiting the size of a policy expression to 4096 nodes,
where a node is a one of the following elements: wsp:Policy, wsp:All, wsp:ExactlyOne,
wsp:policyReference.The policy import logic also automatically normalizes policy expressions.
Nested policy expressions and the wsp:Optional attribute are not normalized. The amount of
normalization processing done is limited to 4096 steps, where each step yields a policy assertion,
or a child element of a wsp:ExactlyOne element.The WsdlImporter type tries up to 32
combinations of policy alternatives attached to the different WSDL policy subjects. If no
combination imports cleanly, the first combination is used to construct a partial custom binding.
Error Handling
Both the MetadataExporter and the MetadataImporter types expose an Errors property that
can contain a collection of error and warning messages encountered during the export and import
processes, respectively, that can be used when implementing tools.The WsdlImporter type
generally throws an exception for an exception caught during the import process and adds a
corresponding error to its Errors property. The ImportAllContracts, ImportAllBindings,
ImportAllEndpoints, and ImportEndpoints methods, however, do not throw these exceptions, so
you must check the Errors property to determine if any issues occurred when calling these
methods.The WsdlExporter type rethrows any exceptions caught during the export process.
These exceptions are not captured as errors in the Errors property. Once the WsdlExporter
throws an exception, it is in a faulted state and cannot be reused. The WsdlExporter does add
Resource Links for 70-513 WCF Certification Exam
24
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
warnings to its Errors property when an operation cannot be exported because it uses wildcard
actions and when duplicate binding names are encountered.
In This Section
How to: Import Metadata into Service Endpoints
Describes how to import downloaded metadata into description objects.
How to: Export Metadata from Service Endpoints
Describes how to export description objects into metadata.
ServiceDescription and WSDL Reference
Describes the mapping between the description objects and WSDL.
How to: Use Svcutil.exe to Export Metadata from Compiled Service Code
Describes the use of Svcutil.exe to export metadata for services, contracts, and data types in
compiled assemblies.
Data Contract Schema Reference
Describes the subset of the XML Schema (XSD) used by DataContractSerializer to describe
common language run-time (CLR) types for XML serialization.
Publishing Metadata
Windows Communication Foundation (WCF) services publish metadata by publishing one or
more metadata endpoints. Publishing service metadata makes the metadata available using
standardized protocols, such as WS-MetadataExchange (MEX) and HTTP/GET requests.
Metadata endpoints are similar to other service endpoints in that they have an address, a binding,
and a contract, and they can be added to a service host through configuration or imperative code.
Publishing Metadata Endpoints
To publish metadata endpoints for a WCF service, you first must add the
ServiceMetadataBehavior service behavior to the service. Adding a
System.ServiceModel.Description.ServiceMetadataBehavior instance allows your service to
expose metadata endpoints. Once you add the
System.ServiceModel.Description.ServiceMetadataBehavior service behavior, you can then
expose metadata endpoints that support the MEX protocol or that respond to HTTP/GET
requests.
Resource Links for 70-513 WCF Certification Exam
25
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The System.ServiceModel.Description.ServiceMetadataBehavior uses a WsdlExporter to
export metadata for all service endpoints in your service. For more information about exporting
metadata from a service, see Exporting and Importing Metadata.
The System.ServiceModel.Description.ServiceMetadataBehavior adds a
ServiceMetadataExtension instance as an extension to your service host. The
System.ServiceModel.Description.ServiceMetadataExtension provides the implementation
for the metadata publishing protocols. You can also use the
System.ServiceModel.Description.ServiceMetadataExtension to get the service's metadata at
runtime by accessing the System.ServiceModel.Description.ServiceMetadataExtension.Metadata
property.
MEX Metadata Endpoints
To add metadata endpoints that use the MEX protocol, add service endpoints to your service host
that use the IMetadataExchange service contract. WCF includes an IMetadataExchange
interface with this service contract name that you can use as part of the WCF programming
model. WS-MetadataExchange endpoints, or MEX endpoints, can use one of the four default
bindings that the static factory methods expose on the MetadataExchangeBindings class to match
the default bindings used by WCF tools such as Svcutil.exe. You can also configure MEX
metadata endpoints using your own custom binding.
HTTP GET Metadata Endpoints
To add a metadata endpoint to your service that responds to HTTP/GET requests, set the
HttpGetEnabled property on the System.ServiceModel.Description.ServiceMetadataBehavior
to true. You can also configure a metadata endpoint that uses HTTPS by setting the
HttpsGetEnabled property on the
System.ServiceModel.Description.ServiceMetadataBehavior to true.
In This Section
How to: Publish Metadata for a Service Using a Configuration File
Demonstrates how to configure a WCF service to publish metadata so that clients can retrieve
the metadata using a WS-MetadataExchange or an HTTP/GET request using the ?wsdl query
string.
How to: Publish Metadata for a Service Using Code
Resource Links for 70-513 WCF Certification Exam
26
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Demonstrates how to enable metadata publishing for a WCF service in code so that clients can
retrieve the metadata using a WS-MetadataExchange or an HTTP/GET request using the ?wsdl
query string.
Retrieving Metadata
Metadata retrieval is the process of requesting and retrieving metadata from a metadata endpoint,
such as a WS-MetadataExchange (MEX) metadata endpoint or an HTTP/GET metadata
endpoint.
Retrieving Metadata from the Command Line Using
Svcutil.exe
You can retrieve service metadata using WS-MetadataExchange or HTTP/GET requests by
using the ServiceModel Metadata Utility Tool (Svcutil.exe) tool and passing the /target:metadata
switch and an address. Svcutil.exe downloads the metadata at the specified address and saves the
file to disk. Svcutil.exe uses a System.ServiceModel.Description.MetadataExchangeClient
instance internally and loads from configuration the IMetadataExchange endpoint configuration
whose name matches the scheme of the address passed to Svcutil.exe as input.
Retrieving Metadata Programmatically Using the
MetadataExchangeClient
Windows Communication Foundation (WCF) can retrieve service metadata using standardized
protocols such as WS-MetadataExchange and HTTP/GET requests. Both of these protocols are
supported by the MetadataExchangeClient type. You retrieve service metadata using the
System.ServiceModel.Description.MetadataExchangeClient type by providing an address for
the metadata endpoint and an optional binding. The binding used by a
System.ServiceModel.Description.MetadataExchangeClient instance can be one of the
default bindings from the MetadataExchangeBindings static class, a user-supplied binding, or a
binding loaded from an endpoint configuration for the IMetadataExchange contract. The
System.ServiceModel.Description.MetadataExchangeClient can also resolve HTTP URL
references to metadata using the HttpWebRequest type.
Resource Links for 70-513 WCF Certification Exam
27
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
By default, a System.ServiceModel.Description.MetadataExchangeClient instance is tied to a
single ChannelFactory instance. You can change or replace the
System.ServiceModel.ChannelFactory instance used by a
System.ServiceModel.Description.MetadataExchangeClient by overriding the
GetChannelFactory virtual method. Similarly, you can change or replace the HttpWebRequest
instance used by a System.ServiceModel.Description.MetadataExchangeClient to make
HTTP/GET requests by overriding the
System.ServiceModel.Description.MetadataExchangeClient.GetWebRequest(System.Uri,System
.String,System.String) virtual method.
In This Section
How to: Use Svcutil.exe to Download Metadata Documents
Demonstrates how to use Svcutil.exe to download metadata documents.
How to: Use MetadataResolver to Obtain Binding Metadata Dynamically
Demonstrates how to use the System.ServiceModel.Description.MetadataResolver to obtain
binding metadata dynamically at runtime.
How to: Use MetadataExchangeClient to Retrieve Metadata
Demonstrates how to use the System.ServiceModel.Description.MetadataExchangeClient
class to download metadata files into a System.ServiceModel.Description.MetadataSet object
that contains System.ServiceModel.Description.MetadataSection objects to write to files or for
other uses.
Using Metadata
Service metadata contains a machine-readable description of the service. Service metadata
includes descriptions of the service endpoints, bindings, contracts, operations, and messages.
You can use service metadata for a variety of purposes, including automatically generating a
client for consuming the service, implementing the service description, and dynamically
updating the binding for a client.
In This Section
Understanding Generated Client Code
Describes the different classes and interfaces the Svcutil.exe tool generates.
Resource Links for 70-513 WCF Certification Exam
28
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
How to: Retrieve Metadata and Implement a Compliant Service
Demonstrates how to retrieve metadata using Svcutil.exe and implement a compliant service.
Generating a WCF Client from Service Metadata
Demonstrates how to retrieve metadata using Svcutil.exe and generate a Windows
Communication Foundation (WCF) client.
Security Considerations with Metadata
When using the metadata features in Windows Communication Foundation (WCF), consider the
security implications of publishing, retrieving, and using service metadata.
When to Publish Metadata
WCF services do not publish metadata by default. To publish metadata for a WCF service you
must explicitly enable metadata publishing by adding metadata endpoints to your service (see
Publishing Metadata). Leaving metadata publishing disabled reduces the attack surface for your
service and lowers the risk of unintentional information disclosure. Not all services must publish
metadata. If you do not have to publish metadata, consider leaving it turned off. Note that you
can still generate metadata and client code directly from your service assemblies using the
ServiceModel Metadata Utility Tool (Svcutil.exe). For more information about using Svcutil.exe
to export metadata, see How to: Use Svcutil.exe to Export Metadata from Compiled Service
Code.
Publishing Metadata Using a Secure Binding
The default metadata bindings that WCF provides are not secure and they allow anonymous
access to the metadata. The service metadata that a WCF service publishes contains a detailed
description about the service and may intentionally or unintentionally contain sensitive
information. For example, service metadata may contain information about infrastructure
operations that was not intended to be broadcast publicly. To protect service metadata from
unauthorized access, you can use a secure binding for your metadata endpoint. Metadata
endpoints respond to HTTP/GET requests that can use Secure Sockets Layer (SSL) to secure the
metadata. For more information, see How to: Secure Metadata Endpoints.Securing your
metadata endpoints also provides a way for requesters to securely retrieve service metadata
without the risk of tampering or spoofing.
Resource Links for 70-513 WCF Certification Exam
29
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Using Only Trusted Metadata
You can use service metadata to automatically construct the run-time components required to
call the service. You can also use metadata at design time to develop a client application or at
runtime to dynamically update the binding a client uses to call a service. Service metadata can be
tampered with or spoofed when retrieved in an insecure manner. Tampered metadata can redirect
your client to a malicious service, contain compromised security settings, or contain malicious
XML structures. Metadata documents can be large and are frequently saved to the file system.
To protect against tampering and spoofing, use a secure binding to request service metadata
when one is available.
Using Safe Techniques for Processing Metadata
Service metadata is frequently retrieved from a service over a network using standardized
protocols such as WS-MetadataExchange (MEX). Many metadata formats include referencing
mechanisms for pointing to additional metadata. The MetadataExchangeClient type
automatically processes references for you in Web Services Description Language (WSDL)
documents, XML Schema, and MEX documents. The size of the MetadataSet object created
from the retrieved metadata is directly proportional to the MaximumResolvedReferences value
for the MetadataExchangeClient instance that is used and the MaxReceivedMessageSize value
for the binding being used by that MetadataExchangeClient instance. Set these quotas to
appropriate values as dictated by your scenario.
In WCF, service metadata is processed as XML. When processing XML documents, applications
should protect themselves against malicious XML structures. Use the XmlDictionaryReader
with appropriate quotas when processing XML and also set the ProhibitDtd property on the
XmlReaderSettings object for your XmlReader instance to true.The metadata system in WCF is
extensible and metadata extensions can be registered in your application configuration file (see
Extending the Metadata System). Metadata extensions can run arbitrary code, so you should
protect your application configuration file with appropriate access control lists (ACLs) and
register only trusted metadata extension implementations.
Validating Generated Clients
Resource Links for 70-513 WCF Certification Exam
30
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
When generating client code from metadata retrieved from a source that is not trusted, validate
the generated client code to ensure that the generated client conforms to your client applications
security policies. You can use a validating behavior to check settings on your client binding or
visually inspect code generated by tools. For an example of how to implement a client that
validates behaviors, see Client Validation.
Protecting Application Configuration Files
A service's application configuration file may control how and if metadata is published. It is a
good idea to protect the application configuration file with appropriate access control lists
(ACLs) to ensure an attacker cannot modify such settings.
Serialization and Deserialization
Windows Communication Foundation (WCF) includes a new serialization engine, the
DataContractSerializer. The DataContractSerializer translates between .NET Framework
objects and XML, in both directions. This topic explains how the serializer works.
When serializing .NET Framework objects, the serializer understands a variety of serialization
programming models, including the new data contract model. For a full list of supported types,
see Types Supported by the Data Contract Serializer. For an introduction to data contracts, see
Using Data Contracts. When deserializing XML, the serializer uses the XmlReader and
XmlWriter classes. It also supports the XmlDictionaryReader and XmlDictionaryWriter classes
to enable it to produce optimized XML in some cases, such as when using the WCF binary XML
format.WCF also includes a companion serializer, the NetDataContractSerializer. The
NetDataContractSerializer is similar to the BinaryFormatter and SoapFormatter serializers
because it also emits .NET Framework type names as part of the serialized data. It is used when
the same types are shared on the serializing and the deserializing ends. Both the
DataContractSerializer and the NetDataContractSerializer derive from a common base class,
the XmlObjectSerializer.
Caution:
The DataContractSerializer serializes strings containing control characters with a hexadecimal value
below 20 as XML entities. This may cause a problem with a non-WCF client went sending such data to a
WCF service.
Resource Links for 70-513 WCF Certification Exam
31
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Creating a DataContractSerializer Instance
Constructing an instance of the DataContractSerializer is an important step. After construction,
you cannot change any of the settings.
Specifying the Root Type
The root type is the type of which instances are serialized or deserialized. The
DataContractSerializer has many constructor overloads, but, at a minimum, a root type must be
supplied using the type parameter. A serializer created for a certain root type cannot be used to
serialize (or deserialize) another type, unless the type is derived from the root type. The
following example shows two classes.
C#
VB
[DataContract]
publicclass Person
{
// Code not shown.
}
[DataContract]
publicclass PurchaseOrder
{
// Code not shown.
}
This code constructs an instance of the DataContractSerializer that can be used only to
serialize or deserialize instances of the Person class.
C#
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
//This can now be used to serialize/deserialize Person but not PurchaseOrder.
Specifying Known Types
If polymorphism is involved in the types being serialized that is not already handled using the
KnownTypeAttribute attribute or some other mechanism, a list of possible known types must be
passed to the serializers constructor using the knownTypes parameter. For more information
about known types, see Data Contract Known Types.
Resource Links for 70-513 WCF Certification Exam
32
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The following example shows a class, LibraryPatron, that includes a collection of a specific type,
the LibraryItem. The second class defines the LibraryItem type. The third and four classes (Book and
Newspaper) inherit from the LibraryItem class.
VB
<DataContract()> _
PublicClass LibraryPatron
<DataMember()> _
Public borrowedItems() As LibraryItem
EndClass
<DataContract()> _
PublicClass LibraryItem
'code not shown
EndClass'LibraryItem
<DataContract()> _
PublicClass Book
Inherits LibraryItem
'code not shown
EndClass

<DataContract()> _
PublicClass Newspaper
Inherits LibraryItem
'code not shown
EndClass
The following code constructs an instance of the serializer using the knownTypes parameter.
C#
//Create a serializer for the inherited types using the knownType parameter.
Type[] knownTypes = new Type[] { typeof(Book), typeof(Newspaper) };
DataContractSerializer dcs =new DataContractSerializer(typeof(LibraryPatron), knownTypes);
// All types are known after construction.
Specifying the Default Root Name and Namespace
Normally, when an object is serialized, the default name and namespace of the outermost XML
element are determined according to the data contract name and namespace. The names of all
inner elements are determined from data member names, and their namespace is the data
Resource Links for 70-513 WCF Certification Exam
33
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
contracts namespace. The following example sets Name and Namespace values in the constructors
of the DataContractAttribute and DataMemberAttribute classes.
C#
[DataContract(Name = "PersonContract", Namespace = "http://schemas.contoso.com")]
publicclass Person2
{
[DataMember(Name = "AddressMember")]
public Address theAddress;
}
[DataContract(Name = "AddressContract", Namespace = "http://schemas.contoso.com")]
publicclass Address
{
[DataMember(Name = "StreetMember")]
publicstring street;
}
Serializing an instance of the Person class produces XML similar to the following.
<PersonContract xmlns="http://schemas.contoso.com">
<AddressMember>
<StreetMember>123 Main Street</StreetMember>
</AddressMember>
</PersonContract>
However, you can customize the default name and namespace of the root element by passing the
values of the rootName and rootNamespace parameters to the DataContractSerializer
constructor. Note that the rootNamespace does not affect the namespace of the contained
elements that correspond to data members. It affects only the namespace of the outermost
element.These values can be passed as strings or instances of the XmlDictionaryString class to
allow for their optimization using the binary XML format.
Setting the Maximum Objects Quota
Some DataContractSerializer constructor overloads have a maxItemsInObjectGraph parameter.
This parameter determines the maximum number of objects the serializer serializes or
deserializes in a single ReadObject method call. (The method always reads one root object, but
this object may have other objects in its data members. Those objects may have other objects,
and so on.) The default is 65536. Note that when serializing or deserializing arrays, every array
Resource Links for 70-513 WCF Certification Exam
34
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
entry counts as a separate object. Also, note that some objects may have a large memory
representation, and so this quota alone may not be sufficient to prevent a denial of service attack.
For more information, see Security Considerations for Data. If you need to increase this quota
beyond the default value, it is important to do so both on the sending (serializing) and receiving
(deserializing) sides because it applies to both when reading and writing data.
Round Trips
A round trip occurs when an object is deserialized and re-serialized in one operation. Thus, it
goes from XML to an object instance, and back again into an XML stream.Some
DataContractSerializer constructor overloads have an ignoreExtensionDataObject parameter,
which is set to false by default. In this default mode, data can be sent on a round trip from a
newer version of a data contract through an older version and back to the newer version without
loss, as long as the data contract implements the IExtensibleDataObject interface. For example,
suppose version 1 of the Person data contract contains the Name and PhoneNumber data members,
and version 2 adds a Nickname member. If IExtensibleDataObject is implemented, when sending
information from version 2 to version 1, the Nickname data is stored, and then re-emitted when the
data is serialized again; therefore, no data is lost in the round trip. For more information, see
Forward-Compatible Data Contracts and Data Contract Versioning.
Security and Schema Validity Concerns with Round Trips
Round trips may have security implications. For example, deserializing and storing large
amounts of extraneous data may be a security risk. There may be security concerns about re-
emitting this data that there is no way to verify, especially if digital signatures are involved. For
example, in the previous scenario, the version 1 endpoint could be signing a Nickname value that
contains malicious data. Finally, there may be schema validity concerns: an endpoint may want
to always emit data that strictly adheres to its stated contract and not any extra values. In the
previous example, the version 1 endpoints contract says that it emits only Name and PhoneNumber,
and if schema validation is being used, emitting the extra Nickname value causes validation to fail.
Enabling and Disabling Round Trips
To turn off round trips, do not implement the IExtensibleDataObject interface. If you have no
control over the types, set the ignoreExtensionDataObject parameter to true to achieve the same
effect.
Resource Links for 70-513 WCF Certification Exam
35
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Object Graph Preservation
Normally, the serializer does not care about object identity, as in the following code.
C#
[DataContract]
publicclass PurchaseOrder
{
[DataMember]
public Address billTo;
[DataMember]
public Address shipTo;
}

[DataContract]
publicclass Address
{
[DataMember]
publicstring street;
}
The following code creates a purchase order.
C#
//Construct a purchase order:
Address adr = new Address();
adr.street = "123 Main St.";
PurchaseOrder po = new PurchaseOrder();
po.billTo = adr;
po.shipTo = adr;

Notice that billTo and shipTo fields are set to the same object instance. However, the generated
XML duplicates the information duplicated, and looks similar to the following XML.
<PurchaseOrder>
<billTo><street>123 Main St.</street></billTo>
<shipTo><street>123 Main St.</street></shipTo>
</PurchaseOrder>
However, this approach has the following characteristics, which may be undesirable:
Performance. Replicating data is inefficient.
Resource Links for 70-513 WCF Certification Exam
36
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Circular references. If objects refer to themselves, even through other objects, serializing by replication
results in an infinite loop. (The serializer throws a SerializationException if this happens.)
Semantics. Sometimes it is important to preserve the fact that two references are to the same object, and
not to two identical objects.
For these reasons, some DataContractSerializer constructor overloads have a
preserveObjectReferences parameter (the default is false). When this parameter is set to true, a
special method of encoding object references, which only WCF understands, is used. When set
to true, the XML code example now resembles the following.
<PurchaseOrder ser:id="1">
<billTo ser:id="2"><street ser:id="3">123 Main St.</street></billTo>
<shipTo ser:ref="2"/>
</PurchaseOrder>
The "ser" namespace refers to the standard serialization namespace,
http://schemas.microsoft.com/2003/10/Serialization/. Each piece of data is serialized only once
and given an ID number, and subsequent uses result in a reference to the already serialized data.
Note:
If both "id" and "ref" attributes are present in the data contract XMLElement, then the "ref" attribute is
honored and the "id" attribute is ignored.
It is important to understand the limitations of this mode:
The XML the DataContractSerializer produces with preserveObjectReferences set to true is not
interoperable with any other technologies, and can be accessed only by another DataContractSerializer
instance, also with preserveObjectReferences set to true.
There is no metadata (schema) support for this feature. The schema that is produced is valid only for the
case when preserveObjectReferences is set to false.
This feature may cause the serialization and deserialization process to run slower. Although data does not
have to be replicated, extra object comparisons must be performed in this mode.
Caution:
When the preserveObjectReferences mode is enabled, it is especially important to set the
maxItemsInObjectGraph value to the correct quota. Due to the way arrays are handled in this mode, it is
easy for an attacker to construct a small malicious message that results in large memory consumption
limited only by the maxItemsInObjectGraph quota.
Specifying a Data Contract Surrogate
Resource Links for 70-513 WCF Certification Exam
37
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Some DataContractSerializer constructor overloads have a dataContractSurrogate parameter,
which may be set to null. Otherwise, you can use it to specify a data contract surrogate, which
is a type that implements the IDataContractSurrogate interface. You can then use the interface to
customize the serialization and deserialization process. For more information, see Data Contract
Surrogates.
Serialization
The following information applies to any class that inherits from the XmlObjectSerializer,
including the DataContractSerializer and NetDataContractSerializer classes.
Simple Serialization
The most basic way to serialize an object is to pass it to the WriteObject method. There are three
overloads, one each for writing to a Stream, an XmlWriter, or an XmlDictionaryWriter. With
the Stream overload, the output is XML in the UTF-8 encoding. With the
XmlDictionaryWriter overload, the serializer optimizes its output for binary XML.
When using the WriteObject method, the serializer uses the default name and namespace for the
wrapper element and writes it out along with the contents (see the previous Specifying the
Default Root Name and Namespace section). The following example demonstrates writing with
an XmlDictionaryWriter.
C#
Person p = new Person();
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
XmlDictionaryWriter xdw = XmlDictionaryWriter.CreateTextWriter(someStream,Encoding.UTF8 );
dcs.WriteObject(xdw, p);

This produces XML similar to the following.
<Person>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Step-By-Step Serialization
Use the WriteStartObject, WriteObjectContent, and WriteEndObject methods to write the end
element, write the object contents, and close the wrapper element, respectively.
Resource Links for 70-513 WCF Certification Exam
38
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Note:
There are no Stream overloads of these methods.
This step-by-step serialization has two common uses. One is to insert contents such as attributes
or comments between WriteStartObject and WriteObjectContent, as shown in the following
example.
C#
dcs.WriteStartObject(xdw, p);
xdw.WriteAttributeString("serializedBy", "myCode");
dcs.WriteObjectContent(xdw, p);
dcs.WriteEndObject(xdw);
This produces XML similar to the following.
<Person serializedBy="myCode">
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Another common use is to avoid using WriteStartObject and WriteEndObject entirely, and to
write your own custom wrapper element (or even skip writing a wrapper altogether), as shown in
the following code.
C#
xdw.WriteStartElement("MyCustomWrapper");
dcs.WriteObjectContent(xdw, p);
xdw.WriteEndElement();
This produces XML similar to the following.
<MyCustomWrapper>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</MyCustomWrapper>
Note:
Using step-by-step serialization may result in schema-invalid XML.
Deserialization
The following information applies to any class that inherits from the XmlObjectSerializer,
including the DataContractSerializer and NetDataContractSerializer classes.The most basic
Resource Links for 70-513 WCF Certification Exam
39
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
way to deserialize an object is to call one of the ReadObject method overloads. There are three
overloads, one each for reading with a XmlDictionaryReader, an XmlReader, or a Stream.
Note that the Stream overload creates a textual XmlDictionaryReader that is not protected by
any quotas, and should be used only to read trusted data. Also note that the object the
ReadObject method returns must be cast to the appropriate type. The following code constructs
an instance of the DataContractSerializer and an XmlDictionaryReader, then deserializes a
Person instance.
C#
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
Person p = (Person)dcs.ReadObject(reader);
Before calling the ReadObject method, position the XML reader on the wrapper element or on a
non-content node that precedes the wrapper element. You can do this by calling the Read method
of the XmlReader or its derivation, and testing the NodeType, as shown in the following code.
C#
DataContractSerializer ser = new DataContractSerializer(typeof(Person),"Customer", @"http://www.contoso.com");
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (ser.IsStartObject(reader))
{
Console.WriteLine("Found the element");
Person p = (Person)ser.ReadObject(reader);
Console.WriteLine("{0} {1} id:{2}",
p.Name , p.Address);
}
Console.WriteLine(reader.Name);
break;
}
}
Resource Links for 70-513 WCF Certification Exam
40
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

Note that you can read attributes on this wrapper element before handing the reader to ReadObject.
When using one of the simple ReadObject overloads, the deserializer looks for the default name
and namespace on the wrapper element (see the preceding section, Specifying the Default Root
Name and Namespace) and throws an exception if it finds an unknown element. In the
preceding example, the <Person> wrapper element is expected. The IsStartObject method is called
to verify that the reader is positioned on an element that is named as expected. There is a way to
disable this wrapper element name check; some overloads of the ReadObject method take the
Boolean parameter verifyObjectName, which is set to true by default. When set to false, the
name and namespace of the wrapper element is ignored. This is useful for reading XML that was
written using the step-by-step serialization mechanism described previously.
Using the NetDataContractSerializer
The primary difference between the DataContractSerializer and the
NetDataContractSerializer is that the DataContractSerializer uses data contract names,
whereas the NetDataContractSerializer outputs full .NET Framework assembly and type
names in the serialized XML. This means that the exact same types must be shared between the
serialization and deserialization endpoints. This means that the known types mechanism is not
required with the NetDataContractSerializer because the exact types to be deserialized are
always known. However, several problems can occur:
Security. Any type found in the XML being deserialized is loaded. This can be exploited to force the
loading of malicious types. Using the NetDataContractSerializer with untrusted data should be done
only if a Serialization Binder is used (using the Binder property or constructor parameter). The binder
permits only safe types to be loaded. The Binder mechanism is identical to the one that types in the
System.Runtime.Serialization namespace use.
Versioning. Using full type and assembly names in the XML severely restricts how types can be
versioned. The following cannot be changed: type names, namespaces, assembly names, and assembly
versions. Setting the AssemblyFormat property or constructor parameter to Simple instead of the default
value of Full allows for assembly version changes, but not for generic parameter types.
Interoperability. Because .NET Framework type and assembly names are included in the XML, platforms
other than the .NET Framework cannot access the resulting data.
Resource Links for 70-513 WCF Certification Exam
41
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Performance. Writing out the type and assembly names significantly increases the size of the resulting
XML.This mechanism is similar to binary or SOAP serialization used by .NET Framework remoting
(specifically, the BinaryFormatter and the SoapFormatter).
Using the NetDataContractSerializer is similar to using the DataContractSerializer, with the
following differences:
The constructors do not require you to specify a root type. You can serialize any type with the same
instance of the NetDataContractSerializer.
The constructors do not accept a list of known types. The known types mechanism is unnecessary if type
names are serialized into the XML.
The constructors do not accept a data contract surrogate. Instead, they accept an ISurrogateSelector
parameter called surrogateSelector (which maps to the SurrogateSelector property). This is a legacy
surrogate mechanism.
The constructors accept a parameter called assemblyFormat of the FormatterAssemblyStyle that maps to
the AssemblyFormat property. As discussed previously, this can be used to enhance the versioning
capabilities of the serializer. This is identical to the FormatterAssemblyStyle mechanism in binary or
SOAP serialization.
The constructors accept a StreamingContext parameter called context that maps to the Context property.
You can use this to pass information into types being serialized. This usage is identical to that of the
StreamingContext mechanism used in other System.Runtime.Serialization classes.
The Serialize and Deserialize methods are aliases for the WriteObject and ReadObject methods. These
exist to provide a more consistent programming model with binary or SOAP serialization.
For more information about these features, see Binary Serialization.
The XML formats that the NetDataContractSerializer and the DataContractSerializer use are
normally not compatible. That is, attempting to serialize with one of these serializers and
deserialize with the other is not a supported scenario.
Also, note that the NetDataContractSerializer does not output the full .NET Framework type
and assembly name for each node in the object graph. It outputs that information only where it is
ambiguous. That is, it outputs at the root object level and for any polymorphic cases.
Using the XmlSerializer Class
Resource Links for 70-513 WCF Certification Exam
42
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Windows Communication Foundation (WCF) can use two different serialization technologies to
turn the data in your application into XML that is transmitted between clients and services, a
process called serialization.
DataContractSerializer as the Default
By default WCF uses the DataContractSerializer class to serialize data types. This serializer
supports the following types:
Primitive types (for example, integers, strings, and byte arrays), as well as some special types, such as
XmlElement and DateTime, which are treated as primitives.
Data contract types (types marked with the DataContractAttribute attribute).
Types marked with the SerializableAttribute attribute, which include types that implement the
ISerializable interface.
Types that implement the IXmlSerializable interface.
Many common collection types, which include many generic collection types.
Many .NET Framework types fall into the latter two categories and are thus serializable. Arrays
of serializable types are also serializable. For a complete list, see Specifying Data Transfer in
Service Contracts.
The DataContractSerializer, used together with data contract types, is the recommended way to
write new WCF services. For more information, see Using Data Contracts.
When to Use the XmlSerializer Class
WCF also supports the XmlSerializer class. The XmlSerializer class is not unique to WCF. It is
the same serialization engine that ASP.NET Web services use. The XmlSerializer class supports
a much narrower set of types than the DataContractSerializer class, but allows much more
control over the resulting XML and supports much more of the XML Schema definition
language (XSD) standard. It also does not require any declarative attributes on the serializable
types. For more information, see the XML Serialization topic in the .NET Framework
documentation. The XmlSerializer class does not support data contract types.
When using Svcutil.exe or the Add Service Reference feature in Visual Studio to generate client
code for a third-party service, or to access a third-party schema, an appropriate serializer is
automatically selected for you. If the schema is not compatible with the
DataContractSerializer, the XmlSerializer is selected.
Resource Links for 70-513 WCF Certification Exam
43
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Manually Switching to the XmlSerializer
At times, you may have to manually switch to the XmlSerializer. This happens, for example, in
the following cases:
When migrating an application from ASP.NET Web services to WCF, you may want to reuse existing,
XmlSerializer-compatible types instead of creating new data contract types.
When precise control over the XML that appears in messages is important, but a Web Services
Description Language (WSDL) document is not available, for example, when creating a service with
types that have to comply to a certain standardized, published schema that is not compatible with the
DataContractSerializer.
When creating services that follow the legacy SOAP Encoding standard.
In these and other cases, you can manually switch to the XmlSerializer class by applying the
XmlSerializerFormatAttribute attribute to your service, as shown in the following code.
C#
[ServiceContract]
[XmlSerializerFormat]
publicclass BankingService
{
[OperationContract]
publicvoid ProcessTransaction(BankingTransaction bt)
{
// Code not shown.
}
}
//BankingTransaction is not a data contract class,
//but is an XmlSerializer-compatible class instead.
publicclass BankingTransaction
{
[XmlAttribute]
publicstring Operation;
[XmlElement]
public Account fromAccount;
[XmlElement]
public Account toAccount;
[XmlElement]
Resource Links for 70-513 WCF Certification Exam
44
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
publicint amount;
}
//Notice that the Account class must also be XmlSerializer-compatible.
Security Considerations
Note:
It is important to be careful when switching serialization engines. The same type can serialize to XML
differently depending on the serializer being used. If you accidentally use the wrong serializer, you might
be disclosing information from the type that you did not intend to disclose.
For example, the DataContractSerializer class only serializes members marked with the
DataMemberAttribute attribute when serializing data contract types. The XmlSerializer class
serializes any public member. See the type in the following code.
C#
[DataContract]
publicclass Customer
{
[DataMember]
publicstring firstName;
[DataMember]
publicstring lastName;
publicstring creditCardNumber;
}
If the type is inadvertently used in a service contract where the XmlSerializer class is selected,
the creditCardNumber member is serialized, which is probably not intended.
Even though the DataContractSerializer class is the default, you can explicitly select it for your
service (although doing this should never be required) by applying the
DataContractFormatAttribute attribute to the service contract type.
The serializer used for the service is an integral part of the contract and cannot be changed by
selecting a different binding or by changing other configuration settings.Other important security
considerations apply to the XmlSerializer class. First, it is strongly recommended that any WCF
application that uses the XmlSerializer class is signed with a key that is safeguarded from
disclosure. This recommendation applies both when a manual switch to the XmlSerializer is
performed and when an automatic switch is performed (by Svcutil.exe, Add Service Reference,
Resource Links for 70-513 WCF Certification Exam
45
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
or a similar tool). This is because the XmlSerializer serialization engine supports the loading of
pre-generated serialization assemblies as long as they are signed with the same key as the
application. An unsigned application is completely unprotected from the possibility of a
malicious assembly matching the expected name of the pre-generated serialization assembly
being placed in the application folder or the global assembly cache. Of course, an attacker must
first gain write access to one of these two locations to attempt this action.Another threat that
exists whenever you use XmlSerializer is related to write access to the system temporary folder.
The XmlSerializer serialization engine creates and uses temporary serialization assemblies in
this folder. You should be aware that any process with write access to the temporary folder may
overwrite these serialization assemblies with malicious code.
Rules for XmlSerializer support
You cannot directly apply XmlSerializer-compatible attributes to contract operation parameters
or return values. However, they can be applied to typed messages (message contract body parts),
as shown in the following code.
C#
[ServiceContract]
[XmlSerializerFormat]
publicclass BankingService
{
[OperationContract]
publicvoid ProcessTransaction(BankingTransaction bt)
{
//Code not shown.
}
}
[MessageContract]
publicclass BankingTransaction
{
[MessageHeader]
publicstring Operation;
[XmlElement, MessageBodyMember]
public Account fromAccount;
[XmlElement, MessageBodyMember]
Resource Links for 70-513 WCF Certification Exam
46
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
public Account toAccount;
[XmlAttribute, MessageBodyMember]
publicint amount;
}
When applied to typed message members, these attributes override properties that conflict on the
typed message attributes. For example, in the following code, ElementName overrides Name.
C#
[MessageContract]
publicclass BankingTransaction
{
[MessageHeader] publicstring Operation;
//This element will be <fromAcct> and not <from>:
[XmlElement(ElementName="fromAcct"), MessageBodyMember(Name="from")]
public Account fromAccount;
[XmlElement, MessageBodyMember]
public Account toAccount;
[XmlAttribute, MessageBodyMember]
publicint amount;
}
The MessageHeaderArrayAttribute attribute is not supported when using the XmlSerializer.
Note:
In this case, the XmlSerializer throws the following exception, which is released prior to WCF: "An
element declared at the top level of a schema cannot have maxOccurs> 1. Provide a wrapper element for
'more' by using XmlArray or XmlArrayItem instead of XmlElementAttribute, or by using the
Wrapped parameter style."
If you receive such an exception, investigate whether this situation applies.
WCF does not support the SoapIncludeAttribute and XmlIncludeAttribute attributes in message
contracts and operation contracts; use the KnownTypeAttribute attribute instead.
Types that Implement the IXmlSerializable Interface
Types that implement the IXmlSerializable interface are fully supported by the
DataContractSerializer. The XmlSchemaProviderAttribute attribute should always be applied
to these types to control their schema.
Resource Links for 70-513 WCF Certification Exam
47
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Caution:
If you are serializing polymorphic types you must apply the XmlSchemaProviderAttribute to the type
to ensure the correct type is serialized.
There are three varieties of types that implement IXmlSerializable: types that represent arbitrary
content, types that represent a single element, and legacy DataSet types.
Content types use a schema provider method specified by the XmlSchemaProviderAttribute attribute.
The method does not return null and the IsAny property on the attribute is left at its default value of false.
This is the most common usage of IXmlSerializable types.
Element types are used when an IXmlSerializable type must control its own root element name. To mark
a type as an element type, either set the IsAny property on the XmlSchemaProviderAttribute attribute
to true or return null from the schema provider method. Having a schema provider method is optional for
element types you may specify null instead of the method name in the XmlSchemaProviderAttribute.
However, if IsAny is true and a schema provider method is specified, the method must return null.
Legacy DataSet types are IXmlSerializable types that are not marked with the
XmlSchemaProviderAttribute attribute. Instead, they rely on the GetSchema method for schema
generation. This pattern is used for the DataSet type and its typed dataset derives a class in earlier
versions of the .NET Framework, but is now obsolete and is supported only for legacy reasons. Do not
rely on this pattern and always apply the XmlSchemaProviderAttribute to your IXmlSerializable
types.
IXmlSerializable Content Types
When serializing a data member of a type that implements IXmlSerializable and is a content
type as defined previously, the serializer writes the wrapper element for the data member and
passes control to the WriteXml method. The WriteXml implementation can write any XML,
which includes adding attributes to the wrapper element. After WriteXml is done, the serializer
closes the element.When deserializing a data member of a type that implements
IXmlSerializable and is a content type as defined previously, the deserializer positions the XML
reader on the wrapper element for the data member and passes control to the ReadXml method.
The method must read the entire element, including the start and end tags. Make sure your
ReadXml code handles the case where the element is empty. Additionally, your ReadXml
implementation should not rely on the wrapper element being named a particular way. The name
is chosen by the serializer can vary.It is permitted to assign IXmlSerializable content types
Resource Links for 70-513 WCF Certification Exam
48
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
polymorphically, for example, to data members of type Object. It is also permitted for the type
instances to be null. Finally, it is possible to use IXmlSerializable types with object graph
preservation enabled and with the NetDataContractSerializer. All these features require the WCF
serializer to attach certain attributes into the wrapper element ("nil" and "type" in the XML
Schema Instance namespace and "Id", "Ref", "Type" and "Assembly" in a WCF-specific
namespace).
Attributes to Ignore when Implementing ReadXml
Before passing control to your ReadXml code, the deserializer examines the XML element,
detects these special XML attributes, and acts on them. For example, if "nil" is true, a null value
is deserialized and ReadXml is not called. If polymorphism is detected, the contents of the
element are deserialized as if it was a different type. The polymorphically-assigned types
implementation of ReadXml is called. In any case, a ReadXml implementation should ignore
these special attributes because they are handled by the deserializer.
Schema Considerations for IXmlSerializable Content Types
When exporting schema and an IXmlSerializable content type, the schema provider method is
called. An XmlSchemaSet is passed to the schema provider method. The method can add any
valid schema to the schema set. The schema set contains the schema that is already known at the
time when schema export occurs. When the schema provider method must add an item to the
schema set, it must determine whether an XmlSchema with the appropriate namespace already
exists in the set. If it does, the schema provider method must add the new item to the existing
XmlSchema. Otherwise, it must create a new XmlSchema instance. This is important if arrays
of IXmlSerializable types are being used. For example, if you have an IXmlSerializable type
that gets exported as type "A" in namespace "B", it is possible that by the time the schema
provider method is called the schema set already contains the schema for "B" to hold the
"ArrayOfA" type.In addition to adding types to the XmlSchemaSet, the schema provider method
for content types must return a non-null value. It can return an XmlQualifiedName that specifies
the name of the schema type to use for the given IXmlSerializable type. This qualified name
also serves as the data contract name and namespace for the type. It is permitted to return a type
that does not exist in the schema set immediately when the schema provider method returns.
However, it is expected that by the time all related types are exported (the Export method is
Resource Links for 70-513 WCF Certification Exam
49
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
called for all relevant types on the XsdDataContractExporter and the Schemas property is
accessed), the type exists in the schema set. Accessing the Schemas property before all relevant
Export calls have been made can result in an XmlSchemaException. For more information about
the export process, see Exporting Schemas from Classes.The schema provider method can also
return the XmlSchemaType to use. The type may or may not be anonymous. If it is anonymous,
the schema for the IXmlSerializable type is exported as an anonymous type every time the
IXmlSerializable type is used as a data member. The IXmlSerializable type still has a data
contract name and namespace. (This is determined as described in Data Contract Names except
that the DataContractAttribute attribute cannot be used to customize the name.) If it is not
anonymous, it must be one of the types in the XmlSchemaSet. This case is equivalent to
returning the XmlQualifiedName of the type.Additionally, a global element declaration is
exported for the type. If the type does not have the XmlRootAttribute attribute applied to it, the
element has the same name and namespace as the data contract, and its "nillable" property is
true. The only exception to this is the schema namespace
("http://www.w3.org/2001/XMLSchema") if the types data contract is in this namespace, the
corresponding global element is in the blank namespace because it is forbidden to add new
elements to the schema namespace. If the type has the XmlRootAttribute attribute applied to it,
the global element declaration is exported using the following: ElementName, Namespace and
IsNullable properties. The defaults with XmlRootAttribute applied are the data contract name, a
blank namespace and "nillable" being true. The same global element declaration rules apply to
legacy dataset types. Note that the XmlRootAttribute cannot override global element
declarations added through custom code, either added to the XmlSchemaSet using the schema
provider method or through GetSchema for legacy dataset types.
IXmlSerializable Element Types
IXmlSerializable element types have either the IsAny property set to true or have their schema
provider method return null.Serializing and deserializing an element type is very similar to
serializing and deserializing a content type. However, there are some important differences:
The WriteXml implementation is expected to write exactly one element (which could of course contain
multiple child elements). It should not be writing attributes outside of this single element, multiple sibling
elements or mixed content. The element may be empty.
Resource Links for 70-513 WCF Certification Exam
50
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The ReadXml implementation should not read the wrapper element. It is expected to read the one
element that WriteXml produces.
When serializing an element type regularly (for example, as a data member in a data contract), the
serializer outputs a wrapper element before calling WriteXml, as with content types. However, when
serializing an element type at the top level, the serializer does not normally output a wrapper element at
all around the element that WriteXml writes, unless a root name and namespace are explicitly specified
when constructing the serializer in the DataContractSerializer or NetDataContractSerializer
constructors. For more information, see Serialization and Deserialization.
When serializing an element type at the top level without specifying the root name and namespace at
construction time, WriteStartObject and WriteEndObject essentially do nothing and WriteObjectContent
calls WriteXml. In this mode, the object being serialized cannot be null and cannot be polymorphically
assigned. Also, object graph preservation cannot enabled and the NetDataContractSerializer cannot be
used.
When deserializing an element type at the top level without specifying the root name and namespace at
construction time, IsStartObject returns true if it can find the start of any element. ReadObject with the
verifyObjectName parameter set to true behaves in the same way as IsStartObject before actually
reading the object. ReadObject then passes control to ReadXml method.
The schema exported for element types is the same as for the XmlElement type as described in
an earlier section, except that the schema provider method can add any additional schema to the
XmlSchemaSet as with content types. Using the XmlRootAttribute attribute with element
types is not allowed, and global element declarations are never emitted for these types.
Differences from the XmlSerializer
The IXmlSerializable interface and the XmlSchemaProviderAttribute and XmlRootAttribute
attributes are also understood by the XmlSerializer . However, there are some differences in
how these are treated in the data contract model. The important differences are summarized in
the following list:
The schema provider method must be public to be used in the XmlSerializer, but does not have to be
public to be used in the data contract model.
The schema provider method is called when IsAny is true in the data contract model but not with the
XmlSerializer.
Resource Links for 70-513 WCF Certification Exam
51
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
When the XmlRootAttribute attribute is not present for content or legacy dataset types, the
XmlSerializer exports a global element declaration in the blank namespace. In the data contract model,
the namespace used is normally the data contract namespace as described earlier.
Be aware of these differences when creating types that are used with both serialization
technologies.
Importing IXmlSerializable Schema
When importing a schema generated from IXmlSerializable types, there are a few possibilities:
The generated schema may be a valid data contract schema as described in Data Contract Schema
Reference. In this case, schema can be imported as usual and regular data contract types are generated.
The generated schema may not be a valid data contract schema. For example, your schema provider
method may generate schema that involves XML attributes that are not supported in the data contract
model. In this case, you can import the schema as IXmlSerializable types. This import mode is not on by
default but can easily be enabled for example, with the /importXmlTypes command-line switch to the
ServiceModel Metadata Utility Tool (Svcutil.exe). This is described in detail in the Importing Schema to
Generate Classes. Note that you must work directly with the XML for your type instances. You may also
consider using a different serialization technology that supports a wider range of schema see the topic
on using the XmlSerializer.
You may want to reuse your existing IXmlSerializable types in the proxy instead of generating new
ones. In this case, the referenced types feature described in the Importing Schema to Generate Types topic
can be used to indicate the type to reuse. This corresponds to using the /reference switch on svcutil.exe,
which specifies the assembly that contains the types to reuse.
Create data contracts. This objective may include but is not limited to: managing Known Types;
controlling data serialization; using required and order attributes on data members; implementing
versioning using IExtensibleDataObject; POCOs This objective does not include: using custom serializer
(ISerializationSurrogate)
Using Data Contracts
A data contract is a formal agreement between a service and a client that abstractly describes the
data to be exchanged. That is, to communicate, the client and the service do not have to share the
same types, only the same data contracts. A data contract precisely defines, for each parameter or
return type, what data is serialized (turned into XML) to be exchanged.
Data Contract Basics
Resource Links for 70-513 WCF Certification Exam
52
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Windows Communication Foundation (WCF) uses a serialization engine called the Data
Contract Serializer by default to serialize and deserialize data (convert it to and from XML). All
.NET Framework primitive types, such as integers and strings, as well as certain types treated as
primitives, such as DateTime and XmlElement, can be serialized with no other preparation and
are considered as having default data contracts. Many .NET Framework types also have existing
data contracts. For a full list of serializable types, see Types Supported by the Data Contract
Serializer. New complex types that you create must have a data contract defined for them to be
serializable. By default, the DataContractSerializer infers the data contract and serializes all
publicly visible types. All public read/write properties and fields of the type are serialized. You
can opt out members from serialization by using the IgnoreDataMemberAttribute. You can also
explicitly create a data contract by using DataContractAttribute and DataMemberAttribute
attributes. This is normally done by applying the DataContractAttribute attribute to the type.
This attribute can be applied to classes, structures, and enumerations. The
DataMemberAttribute attribute must then be applied to each member of the data contract type
to indicate that it is a data member, that is, it should be serialized. For more information, see
Serializable Types.
Example
The following example shows a service contract (an interface) to which the
ServiceContractAttribute and OperationContractAttribute attributes have been explicitly applied.
The example shows that primitive types do not require a data contract, while a complex type
does.
C#
[ServiceContract]
publicinterface ISampleInterface
{
// No data contract is requred since both the parameter
// and return types are primitive types.
[OperationContract]
double SquareRoot(int root);
// No Data Contract required because both parameter and return
// types are marked with the SerializableAttribute attribute.
[OperationContract]
Resource Links for 70-513 WCF Certification Exam
53
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
System.Drawing.Bitmap GetPicture(System.Uri pictureUri);
// The MyTypes.PurchaseOrder is a complex type, and thus
// requires a data contract.
[OperationContract]
bool ApprovePurchaseOrder(MyTypes.PurchaseOrder po);
}

The following example shows how a data contract for the MyTypes.PurchaseOrder type is created by
applying the DataContractAttribute and DataMemberAttribute attributes to the class and its
members.
C#
namespace MyTypes
{
[DataContract]
publicclass PurchaseOrder
{
privateint poId_value;
// Apply the DataMemberAttribute to the property.
[DataMember]
publicint PurchaseOrderId
{
get { return poId_value; }
set { poId_value = value; }
}
}
}
Notes
The following notes provide items to consider when creating data contracts:
The IgnoreDataMemberAttribute attribute is only honored when used with unmarked types. This
includes types that are not marked with one of the DataContractAttribute, SerializableAttribute,
CollectionDataContractAttribute, or EnumMemberAttribute attributes, or marked as serializable by any
other means (such as IXmlSerializable).
You can apply the DataMemberAttribute attribute to fields, and properties.
Member accessibility levels (internal, private, protected, or public) do not affect the data contract in any
way.
Resource Links for 70-513 WCF Certification Exam
54
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The DataMemberAttribute attribute is ignored if it is applied to static members.
During serialization, property-get code is called for property data members to get the value of the
properties to be serialized.
During deserialization, an uninitialized object is first created, without calling any constructors on the type.
Then all data members are deserialized.
During deserialization, property-set code is called for property data members to set the properties to the
value being deserialized.
For a data contract to be valid, it must be possible to serialize all of its data members. For a full list of
serializable types, see Types Supported by the Data Contract Serializer.
Generic types are handled in exactly the same way as non-generic types. There are no special
requirements for generic parameters. For example, consider the following type.
C#
[DataContract]
publicclass MyGenericType1<T>
{
// Code not shown.
}
This type is serializable whether the type used for the generic type parameter (T) is serializable
or not. Because it must be possible to serialize all data members, the following type is
serializable only if the generic type parameter is also serializable, as shown in the following
code.
C#
[DataContract]
publicclass MyGenericType2<T>
{
[DataMember]
T theData;
}
For a complete code sample of a WCF service that defines a data contract see the Basic Data
Contract sample.
Basic Data Contract
Resource Links for 70-513 WCF Certification Exam
55
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
This sample demonstrates how to implement a data contract. Data contracts allow you to pass
structured data to and from services. This sample is based on the Getting Started Sample but uses
complex numbers instead of basic numeric types.
In this sample, the service is hosted by Internet Information Services (IIS) and the client is a
console application (.exe).
Note:
The setup procedure and build instructions for this sample are located at the end of this topic.
The service contract for this service uses complex numbers, as shown in the following sample
code.
// Define a service contract.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
ComplexNumber Add(ComplexNumber n1, ComplexNumber n2);
[OperationContract]
ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2);
[OperationContract]
ComplexNumber Multiply(ComplexNumber n1, ComplexNumber n2);
[OperationContract]
ComplexNumber Divide(ComplexNumber n1, ComplexNumber n2);
}
The DataContractAttribute and DataMemberAttribute attributes have been applied to the
definition of the ComplexNumber class to indicate which fields of the class can be passed over the
wire between the client and the service, as shown in the following sample code.
[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public class ComplexNumber
{
[DataMember]
public double Real = 0.0D;
[DataMember]
public double Imaginary = 0.0D;
public ComplexNumber(double real, double imaginary)
{
Resource Links for 70-513 WCF Certification Exam
56
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
this.Real = real;
this.Imaginary = imaginary;
}
}
The service implementation calculates and returns the appropriate result, accepting and returning
numbers of the ComplexNumber type.
// This is the service class that implements the service contract.
public class CalculatorService : ICalculator
{
public ComplexNumber Add(ComplexNumber n1, ComplexNumber n2)
{
return new ComplexNumber(n1.Real + n2.Real, n1.Imaginary + n2.Imaginary);
}
public ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2)
{
return new ComplexNumber(n1.Real - n2.Real, n1.Imaginary - n2.Imaginary);
}
public ComplexNumber Multiply(ComplexNumber n1, ComplexNumber n2)
{
double real1 = n1.Real * n2.Real;
double imaginary1 = n1.Real * n2.Imaginary;
double imaginary2 = n2.Real * n1.Imaginary;
double real2 = n1.Imaginary * n2.Imaginary * -1;
return new ComplexNumber(real1 + real2, imaginary1 + imaginary2);
}

public ComplexNumber Divide(ComplexNumber n1, ComplexNumber n2)
{
ComplexNumber conjugate = new ComplexNumber(n2.Real, -1*n2.Imaginary);
ComplexNumber numerator = Multiply(n1, conjugate);
ComplexNumber denominator = Multiply(n2, conjugate);
return new ComplexNumber(numerator.Real / denominator.Real, numerator.Imaginary);
}
}
Resource Links for 70-513 WCF Certification Exam
57
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The client implementation also uses complex numbers. Both the service contract and the data
contract are defined in the source file generatedClient.cs, which is generated by the
ServiceModel Metadata Utility Tool (Svcutil.exe) from service metadata.
// Create a client.
DataContractCalculatorClient client = new DataContractCalculatorClient();
// Call the Add service operation.
ComplexNumber value1 = new ComplexNumber();
value1.Real = 1;
value1.Imaginary = 2;
ComplexNumber value2 = new ComplexNumber();
value2.Real = 3;
value2.Imaginary = 4;
ComplexNumber result = proxy.Add(value1, value2);
Console.WriteLine("Add({0} + {1}i, {2} + {3}i) = {4} + {5}i",
value1.Real, value1.Imaginary, value2.Real, value2.Imaginary,
result.Real, result.Imaginary);

}

When you run the sample, the requests and responses of the operation are displayed in the client
console window. Press ENTER in the client window to shut down the client.

Add(1 + 2i, 3 + 4i) = 4 + 6i
Subtract(1 + 2i, 3 + 4i) = -2 + -2i
Multiply(2 + 3i, 4 + 7i) = -13 + 26i
Divide(3 + 7i, 5 + -2i) = 0.0344827586206897 + 41i

Press <ENTER> to terminate client.
To set up, build, and run the sample
1. Ensure that you have performed the One-Time Setup Procedure for the Windows
Communication Foundation Samples.
2. To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building
the Windows Communication Foundation Samples.
Resource Links for 70-513 WCF Certification Exam
58
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
3. To run the sample in a single- or cross-machine configuration, follow the instructions in Running
the Windows Communication Foundation Samples.
Note:
The samples may already be installed on your machine. Check for the following (default) directory before
continuing. <InstallDrive>:\WF_WCF_Samples
If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows
Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication
Foundation (WCF) and WF samples. This sample is located in the following directory.
<InstallDrive>:\WF_WCF_Samples\WCF\Basic\Contract\Data\Basic
Data Contract Known Types
The KnownTypeAttribute class allows you to specify, in advance, the types that should be
included for consideration during deserialization. For a working example, see the Known Types
example.Normally, when passing parameters and return values between a client and a service,
both endpoints share all of the data contracts of the data to be transmitted. However, this is not
the case in the following circumstances:
The sent data contract is derived from the expected data contract. For more information, see the
section about inheritance in Data Contract Equivalence). In that case, the transmitted data does
not have the same data contract as expected by the receiving endpoint.
The declared type for the information to be transmitted is an interface, as opposed to a class,
structure, or enumeration. Therefore, it cannot be known in advance which type that implements
the interface is actually sent and therefore, the receiving endpoint cannot determine in advance
the data contract for the transmitted data.
The declared type for the information to be transmitted is Object. Because every type inherits
from Object, and it cannot be known in advance which type is actually sent, the receiving
endpoint cannot determine in advance the data contract for the transmitted data. This is a special
case of the first item: Every data contract derives from the default, a blank data contract that is
generated for Object.
Some types, which include .NET Framework types, have members that are in one of the
preceding three categories. For example, Hashtable uses Object to store the actual objects in the
Resource Links for 70-513 WCF Certification Exam
59
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
hash table. When serializing these types, the receiving side cannot determine in advance the data
contract for these members.
The KnownTypeAttribute Class
When data arrives at a receiving endpoint, the WCF runtime attempts to deserialize the data into
an instance of a common language runtime (CLR) type. The type that is instantiated for
deserialization is chosen by first inspecting the incoming message to determine the data contract
to which the contents of the message conform. The deserialization engine then attempts to find a
CLR type that implements a data contract compatible with the message contents. The set of
candidate types that the deserialization engine allows for during this process is referred to as the
deserializer's set of "known types."
One way to let the deserialization engine know about a type is by using the
KnownTypeAttribute. The attribute cannot be applied to individual data members, only to whole
data contract types. The attribute is applied to an outer type that can be a class or a structure. In
its most basic usage, applying the attribute specifies a type as a "known type." This causes the
known type to be a part of the set of known types whenever an object of the outer type or any
object referred to through its members is being deserialized. More than one KnownTypeAttribute
attribute can be applied to the same type.
Known Types and Primitives
Primitive types, as well as certain types treated as primitives (for example, DateTime and
XmlElement) are always "known" and never have to be added through this mechanism.
However, arrays of primitive types have to be added explicitly. Most collections are considered
equivalent to arrays. (Non-generic collections are considered equivalent to arrays of Object). For
an example of the using primitives, primitive arrays, and primitive collections, see Example 4.
Note
Unlike other primitive types, the DateTimeOffset structure is not a known type by default, so it
must be manually added to the list of known types.
Examples
The following examples show the KnownTypeAttribute class in use.
Example 1
There are three classes with an inheritance relationship.
C#
Resource Links for 70-513 WCF Certification Exam
60
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
[DataContract]
publicclass Shape { }
[DataContract(Name = "Circle")]
publicclass CircleType : Shape { }
[DataContract(Name = "Triangle")]
publicclass TriangleType : Shape { }
The following CompanyLogo class can be serialized, but cannot be deserialized if the
ShapeOfLogo member is set to either a CircleType or a TriangleType object, because the
deserialization engine does not recognize any types with data contract names "Circle" or
"Triangle."
C#
[DataContract]
publicclass CompanyLogo
{
[DataMember]
private Shape ShapeOfLogo;
[DataMember]
privateint ColorOfLogo;
}
The correct way to write the CompanyLogo type is shown in the following code.
C#
[DataContract]
[KnownType(typeof(CircleType))]
[KnownType(typeof(TriangleType))]
publicclass CompanyLogo2
{
[DataMember]
private Shape ShapeOfLogo;
[DataMember]
privateint ColorOfLogo;
}
Whenever the outer type CompanyLogo2 is being deserialized, the deserialization engine knows
about CircleType and TriangleType and, therefore, is able to find matching types for the "Circle"
and "Triangle" data contracts.
Example 2
Resource Links for 70-513 WCF Certification Exam
61
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
In the following example, even though both CustomerTypeA and CustomerTypeB have the
Customer data contract, an instance of CustomerTypeB is created whenever a PurchaseOrder is
deserialized, because only CustomerTypeB is known to the deserialization engine.
C#
publicinterface ICustomerInfo
{
string ReturnCustomerName();
}
[DataContract(Name = "Customer")]
publicclass CustomerTypeA : ICustomerInfo
{
publicstring ReturnCustomerName()
{
return"no name";
}
}
[DataContract(Name = "Customer")]
publicclass CustomerTypeB : ICustomerInfo
{
publicstring ReturnCustomerName()
{
return"no name";
}
}
[DataContract]
[KnownType(typeof(CustomerTypeB))]
publicclass PurchaseOrder
{
[DataMember]
ICustomerInfo buyer;
[DataMember]
int amount;
}


Example 3
Resource Links for 70-513 WCF Certification Exam
62
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
In the following example, a Hashtable stores its contents internally as Object. To successfully
deserialize a hash table, the deserialization engine must know the set of possible types that can
occur there. In this case, we know in advance that only Book and Magazine objects are stored in
the Catalog, so those are added using the KnownTypeAttribute attribute.
C#
[DataContract]
publicclass Book { }
[DataContract]
publicclass Magazine { }
[DataContract]
[KnownType(typeof(Book))]
[KnownType(typeof(Magazine))]
publicclass LibraryCatalog
{
[DataMember]
System.Collections.Hashtable theCatalog;
}
Example 4
In the following example, a data contract stores a number and an operation to perform on the
number. The Numbers data member can be an integer, an array of integers, or a List<T> that
contains integers.
Caution
This will only work on the client side if SVCUTIL.EXE is used to generate a WCF proxy.
SVCUTIL.EXE retrieves metadata from the service including any known types. Without this
information a client will not be able to deserialize the types.
C#
[DataContract]
[KnownType(typeof(int[]))]
publicclass MathOperationData
{
privateobject numberValue;
[DataMember]
publicobject Numbers
{
Resource Links for 70-513 WCF Certification Exam
63
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
get { return numberValue; }
set { numberValue = value; }
}
//[DataMember]
//public Operation Operation;
}
This is the application code.
C#
// This is in the service application code:
staticvoid Run()
{
MathOperationData md = new MathOperationData();
// This will serialize and deserialize successfully because primitive
// types like int are always known.
int a = 100;
md.Numbers = a;

// This will serialize and deserialize successfully because the array of
// integers was added to known types.
int[] b = newint[100];
md.Numbers = b;
// This will serialize and deserialize successfully because the generic
// List<int> is equivalent to int[], which was added to known types.
List<int> c = new List<int>();
md.Numbers = c;
// This will serialize but will not deserialize successfully because
// ArrayList is a non-generic collection, which is equivalent to
// an array of type object. To make it succeed, object[]
// must be added to the known types.
ArrayList d = new ArrayList();
md.Numbers = d;
}


Known Types, Inheritance, and Interfaces
Resource Links for 70-513 WCF Certification Exam
64
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
When a known type is associated with a particular type using the KnownTypeAttribute attribute,
the known type is also associated with all of the derived types of that type. For example, see the
following code.
C#
[DataContract]
[KnownType(typeof(Square))]
[KnownType(typeof(Circle))]
publicclass MyDrawing
{
[DataMember]
privateobject Shape;
[DataMember]
privateint Color;
}
[DataContract]
publicclass DoubleDrawing : MyDrawing
{
[DataMember]
privateobject additionalShape;
}
The DoubleDrawing class does not require the KnownTypeAttribute attribute to use Square and
Circle in the AdditionalShape field, because the base class (Drawing) already has these attributes
applied.Known types can be associated only with classes and structures, not interfaces.
Known Types Using Open Generic MethodsIt may be necessary to add a generic type as a known type.
However, an open generic type cannot be passed as a parameter to the KnownTypeAttribute attribute.
This problem can be solved by using an alternative mechanism: Write a method that returns a list
of types to add to the known types collection. The name of the method is then specified as a
string argument to the KnownTypeAttribute attribute due to some restrictions.The method must
exist on the type to which the KnownTypeAttribute attribute is applied, must be static, must
accept no parameters, and must return an object that can be assigned to IEnumerable of Type.
You cannot combine the KnownTypeAttribute attribute with a method name and
KnownTypeAttribute attributes with actual types on the same type. Furthermore, you cannot
apply more than one KnownTypeAttribute with a method name to the same type.
See the following class.
Resource Links for 70-513 WCF Certification Exam
65
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
C#
[DataContract]
publicclass DrawingRecord<T>
{
[DataMember]
private T theData;
[DataMember]
private GenericDrawing<T> theDrawing;
}
The theDrawing field contains instances of a generic class ColorDrawing and a generic class
BlackAndWhiteDrawing, both of which inherit from a generic class Drawing. Normally, both
must be added to known types, but the following is not valid syntax for attributes.
C#
// Invalid syntax for attributes:
// [KnownType(typeof(ColorDrawing<T>))]
// [KnownType(typeof(BlackAndWhiteDrawing<T>))]
Thus, a method must be created to return these types. The correct way to write this type, then, is
shown in the following code.
C#
[DataContract]
[KnownType("GetKnownType")]
publicclass DrawingRecord2<T>
{
[DataMember]
private T TheData;
[DataMember]
private GenericDrawing<T> TheDrawing;
privatestatic Type[] GetKnownType()
{
Type[] t = new Type[2];
t[0] = typeof(ColorDrawing<T>);
t[1] = typeof(BlackAndWhiteDrawing<T>);
return t;
}
}
Resource Links for 70-513 WCF Certification Exam
66
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Additional Ways to Add Known Types
Additionally, known types can be added through a configuration file. This is useful when you do
not control the type that requires known types for proper deserialization, such as when using
third-party type libraries with Windows Communication Foundation (WCF).
The following configuration file shows how to specify a known type in a configuration file.
<configuration>
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="MyCompany.Library.Shape,
MyAssembly, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=XXXXXX, processorArchitecture=MSIL">
<knownType type="MyCompany.Library.Circle,
MyAssembly, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=XXXXXX, processorArchitecture=MSIL"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
</configuration>
In the preceding configuration file a data contract type called MyCompany.Library.Shape is
declared to have MyCompany.Library.Circle as a known type.
Data Contract Versioning
As applications evolve, you may also have to change the data contracts the services use. This
topic explains how to version data contracts. This topic describes the data contract versioning
mechanisms. For a complete overview and prescriptive versioning guidance, see Best Practices:
Data Contract Versioning.
Breaking vs. Nonbreaking Changes
Resource Links for 70-513 WCF Certification Exam
67
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Changes to a data contract can be breaking or nonbreaking. When a data contract is changed in a
nonbreaking way, an application using the older version of the contract can communicate with an
application using the newer version, and an application using the newer version of the contract
can communicate with an application using the older version. On the other hand, a breaking
change prevents communication in one or both directions.
Any changes to a type that do not affect how it is transmitted and received are nonbreaking. Such
changes do not change the data contract, only the underlying type. For example, you can change
the name of a field in a nonbreaking way if you then set the Name property of the
DataMemberAttribute to the older version name. The following code shows version 1 of a data
contract.
C#
// Version 1
[DataContract]
publicclass Person
{
[DataMember]
privatestring Phone;
}
The following code shows a nonbreaking change.
C#
// Version 2. This is a non-breaking change because the data contract
// has not changed, even though the type has.
[DataContract]
publicclass Person
{
[DataMember(Name = "Phone")]
privatestring Telephone;
}
Some changes do modify the transmitted data, but may or may not be breaking. The following
changes are always breaking:
Changing the Name or Namespace value of a data contract.
Changing the order of data members by using the Order property of the DataMemberAttribute.
Renaming a data member.
Resource Links for 70-513 WCF Certification Exam
68
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Changing the data contract of a data member. For example, changing the type of data member from an
integer to a string, or from a type with a data contract named "Customer" to a type with a data contract
named "Person".
The following changes are also possible.
Adding and Removing Data Members
In most cases, adding or removing a data member is not a breaking change, unless you require
strict schema validity (new instances validating against the old schema).
When a type with an extra field is deserialized into a type with a missing field, the extra
information is ignored. (It may also be stored for round-tripping purposes; for more information,
see Forward-Compatible Data Contracts).
When a type with a missing field is deserialized into a type with an extra field, the extra field is
left at its default value, usually zero or null. (The default value may be changed; for more
information, see Version-Tolerant Serialization Callbacks.)
For example, you can use the CarV1 class on a client and the CarV2 class on a service, or you can
use the CarV1 class on a service and the CarV2 class on a client.
C#
// Version 1 of a data contract, on machine V1.
[DataContract(Name = "Car")]
publicclass CarV1
{
[DataMember]
privatestring Model;
}

// Version 2 of the same data contract, on machine V2.
[DataContract(Name = "Car")]
publicclass CarV2
{
[DataMember]
privatestring Model;
[DataMember]
privateint HorsePower;
}
Resource Links for 70-513 WCF Certification Exam
69
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

The version 2 endpoint can successfully send data to the version 1 endpoint. Serializing version 2
of the Car data contract yields XML similar to the following.
<Car>
<Model>Porsche</Model>
<HorsePower>300</HorsePower>
</Car>
The deserialization engine on V1 does not find a matching data member for the HorsePower field,
and discards that data.
Also, the version 1 endpoint can send data to the version 2 endpoint. Serializing version 1 of the
Car data contract yields XML similar to the following.
<Car>
<Model>Porsche</Model>
</Car>
The version 2 deserializer does not know what to set the HorsePower field to, because there is no
matching data in the incoming XML. Instead, the field is set to the default value of 0.
Required Data Members
A data member may be marked as being required by setting the IsRequired property of the
DataMemberAttribute to true. If required data is missing while deserializing, an exception is
thrown instead of setting the data member to its default value.Adding a required data member is
a breaking change. That is, the newer type can still be sent to endpoints with the older type, but
not the other way around. Removing a data member that was marked as required in any prior
version is also a breaking change.Changing the IsRequired property value from true to false is
not breaking, but changing it from false to true may be breaking if any prior versions of the type
do not have the data member in question.
Note:
Although the IsRequired property is set to true, the incoming data may be null or zero, and a type must
be prepared to handle this possibility. Do not use IsRequired as a security mechanism to protect against
bad incoming data.
Omitted Default Values
Resource Links for 70-513 WCF Certification Exam
70
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
It is possible (although not recommended) to set the EmitDefaultValue property on the
DataMemberAttribute attribute to false, as described in Data Member Default Values. If this
setting is false, the data member will not be emitted if it is set to its default value (usually null or
zero). This is not compatible with required data members in different versions in two ways:
A data contract with a data member that is required in one version cannot receive default (null or zero)
data from a different version in which the data member has EmitDefaultValue set to false.
A required data member that has EmitDefaultValue set to false cannot be used to serialize its default
(null or zero) value, but can receive such a value on deserialization. This creates a round-tripping problem
(data can be read in but the same data cannot then be written out). Therefore, if IsRequired is true and
EmitDefaultValue is false in one version, the same combination should apply to all other versions such
that no version of the data contract would be able to produce a value that does not result in a round trip.
Schema Considerations
For an explanation of what schema is produced for data contract types, see Data Contract
Schema Reference.The schema WCF produces for data contract types makes no provisions for
versioning. That is, the schema exported from a certain version of a type contains only those data
members present in that version. Implementing the IExtensibleDataObject interface does not
change the schema for a type.Data members are exported to the schema as optional elements by
default. That is, the minOccurs (XML attribute) value is set to 0. Required data members are
exported with minOccurs set to 1.Many of the changes considered to be nonbreaking are
actually breaking if strict adherence to the schema is required. In the preceding example, a CarV1
instance with just the Model element would validate against the CarV2 schema (which has both
Model and Horsepower, but both are optional). However, the reverse is not true: a CarV2 instance
would fail validation against the CarV1 schema.Round-tripping also entails some additional
considerations. For more information, see the "Schema Considerations" section in Forward-
Compatible Data Contracts.
Other Permitted Changes
Implementing the IExtensibleDataObject interface is a nonbreaking change. However, round-
tripping support does not exist for versions of the type prior to the version in which
IExtensibleDataObject was implemented. For more information, see Forward-Compatible Data
Contracts.
Resource Links for 70-513 WCF Certification Exam
71
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Enumerations
Adding or removing an enumeration member is a breaking change. Changing the name of an
enumeration member is breaking, unless its contract name is kept the same as in the old version
by using the EnumMemberAtttribute attribute. For more information, see Enumeration Types
in Data Contracts.
Collections
Most collection changes are nonbreaking because most collection types are interchangeable with
each other in the data contract model. However, making a noncustomized collection customized
or vice versa is a breaking change. Also, changing the collection's customization settings is a
breaking change; that is, changing its data contract name and namespace, repeating element
name, key element name, and value element name. For more information about collection
customization, see Collection Types in Data Contracts.Naturally, changing the data contract of
contents of a collection (for example, changing from a list of integers to a list of strings) is a
breaking change.
Data Member Order
In some applications, it is useful to know the order in which data from the various data members
is sent or is expected to be received (such as the order in which data appears in the serialized
XML). Sometimes it may be necessary to change this order. This topic explains the ordering
rules.
Basic Rules
The basic rules for data ordering include:
If a data contract type is a part of an inheritance hierarchy, data members of its base types are always first
in the order.
Next in order are the current types data members that do not have the Order property of the
DataMemberAttribute attribute set, in alphabetical order.
Next are any data members that have the Order property of the DataMemberAttribute attribute set.
These are ordered by the value of the Order property first and then alphabetically if there is more than
one member of a certain Order value. Order values may be skipped.
Alphabetical order is established by calling the CompareOrdinal method.
Resource Links for 70-513 WCF Certification Exam
72
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Examples
Consider the following code.
C#
[DataContract]
publicclass BaseType
{
[DataMember]
publicstring zebra;
}
[DataContract]
publicclass DerivedType : BaseType
{
[DataMember(Order = 0)]
publicstring bird;
[DataMember(Order = 1)]
publicstring parrot;
[DataMember]
publicstring dog;
[DataMember(Order = 3)]
publicstring antelope;
[DataMember]
publicstring cat;
[DataMember(Order = 1)]
publicstring albatross;
}

The XML produced is similar to the following.
<DerivedType>
<!-- Zebra is a base data member, and appears first. --><zebra/>
<!-- Cat has no Order, appears alphabetically first. --><cat/>
<!-- Dog has no Order, appears alphabetically last. --><dog/>
<!-- Bird is the member with the smallest Order value --><bird/>
<!-- Albatross has the next Order value, alphabetically first. -->
<albatross/>
<!-- Parrot, with the next Order value, alphabetically last. --><parrot/>
Resource Links for 70-513 WCF Certification Exam
73
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<!-- Antelope is the member with the highest Order value. Note that Order=2 is skipped --><antelope/>
</DerivedType>
Forward-Compatible Data Contracts
A feature of the Windows Communication Foundation (WCF) data contract system is that
contracts can evolve over time in nonbreaking ways. That is, a client with an older version of a
data contract can communicate with a service with a newer version of the same data contract, or
a client with a newer version of a data contract can communicate with an older version of the
same data contract. For more information, see Best Practices: Data Contract Versioning.
You can apply most of the versioning features on an as-needed basis when new versions of an
existing data contract are created. However, one versioning feature, round-tripping, must be built
into the type from the first version in order to work properly.
Round-Tripping
Round-tripping occurs when data passes from a new version to an old version and back to the
new version of a data contract. Round-tripping guarantees that no data is lost. Enabling round-
tripping makes the type forward-compatible with any future changes supported by the data
contract versioning model.
To enable round-tripping for a particular type, the type must implement the
IExtensibleDataObject interface. The interface contains one property, ExtensionData (returning
the ExtensionDataObject type). The property stores any data from future versions of the data
contract that is unknown to the current version.
Example
The following data contract is not forward-compatible with future changes.
C#
[DataContract]
publicclass Person
{
[DataMember]
publicstring fullName;
}
Resource Links for 70-513 WCF Certification Exam
74
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
To make the type compatible with future changes (such as adding a new data member named
"phoneNumber"), implement the IExtensibleDataObject interface.
C#
[DataContract]
publicclass Person : IExtensibleDataObject
{
[DataMember]
publicstring fullName;
private ExtensionDataObject theData;
publicvirtual ExtensionDataObject ExtensionData
{
get { return theData; }
set { theData = value; }
}
}
When the WCF infrastructure encounters data that is not part of the original data contract, the
data is stored in the property and preserved. It is not processed in any other way except for
temporary storage. If the object is returned back to where it originated, the original (unknown)
data is also returned. Therefore, the data has made a round trip to and from the originating
endpoint without loss. Note, however, that if the originating endpoint required the data to be
processed, that expectation is unmet, and the endpoint must somehow detect and accommodate
the change.The ExtensionDataObject type contains no public methods or properties. Thus, it is
impossible to get direct access to the data stored inside the ExtensionData property.
The round-tripping feature may be turned off, either by setting ignoreExtensionDataObject to
true in the DataContractSerializer constructor or by setting the IgnoreExtensionDataObject
property to true on the ServiceBehaviorAttribute. When this feature is off, the deserializer will
not populate the ExtensionData property, and the serializer will not emit the contents of the
property.Create message contracts.This objective may include but is not limited to: body and
header elements; using required and order attributes on members
Using Message Contracts
Typically when building Windows Communication Foundation (WCF) applications, developers
pay close attention to the data structures and serialization issues and do not need to concern
Resource Links for 70-513 WCF Certification Exam
75
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
themselves with the messages in which the data is carried. For these applications, creating data
contracts for the parameters or return values is straightforward. (For more information, see
Specifying Data Transfer in Service Contracts.)However, sometimes complete control over the
structure of a SOAP message is just as important as control over its contents. This is especially
true when interoperability is important or to specifically control security issues at the level of the
message or message part. In these cases, you can create a message contract that enables you to
use a type for a parameter or return value that serializes directly into the precise SOAP message
that you need.This topic discusses how to use the various message contract attributes to create a
specific message contract for your operation.
Using Message Contracts in Operations
WCF supports operations modeled on either the remote procedure call (RPC) style or the
messaging style. In an RPC-style operation, you can use any serializable type, and you have
available to you the features that are available to local calls, such as multiple parameters and ref
and out parameters. In this style, the form of serialization chosen controls the structure of the
data in the underlying messages, but the WCF runtime creates the messages themselves to
support the operation. This enables developers who are not familiar with SOAP and SOAP
messages to quickly and easily create and use service applications. The following code example
shows a service operation modeled on the RPC style.
C#
[OperationContract]
public BankingTransactionResponse PostBankingTransaction(BankingTransaction bt);
Normally, a data contract is sufficient to define the schema for the messages. For instance, in the
preceding example, it is sufficient for most applications if BankingTransaction and
BankingTransactionResponse have data contracts to define the contents of the underlying SOAP
messages. For more information about data contracts, see Using Data Contracts.
However, occasionally it is necessary to precisely control how a type is mapped to a SOAP
message transmitted over the wire. The most common scenario for this is inserting custom SOAP
headers. Another common scenario is to define security properties for the message's headers and
body, that is, to decide whether these elements are digitally signed and encrypted. Messaging-
style operations provide this control.A messaging-style operation has at most one parameter and
one return value where both types are message types; that is, they serialize directly into a
Resource Links for 70-513 WCF Certification Exam
76
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
specified SOAP message structure. This may be any type marked with the
MessageContractAttribute or the Message type. The following code example shows an operation
similar to the preceding RCP-style, but which uses the messaging style. For example, if
BankingTransaction and BankingTransactionResponse are both types that have message contracts, then
the code in the following operations is valid.
C#
[OperationContract]
BankingTransactionResponse Process(BankingTransaction bt);
[OperationContract]
void Store(BankingTransaction bt);
[OperationContract]
BankingTransactionResponse GetResponse();
However, the following code is invalid.
C#
[OperationContract]
bool Validate(BankingTransaction bt);
// Invalid, the return type is not a message contract.
[OperationContract]
void Reconcile(BankingTransaction bt1, BankingTransaction bt2);
// Invalid, there is more than one parameter.
An exception is thrown for any operation that involves a message contract type and that does not
follow one of the valid patterns. Of course, operations that do not involve message contract types
are not subject to these restrictions.If a type has both a message contract and a data contract, only
its message contract is considered when the type is used in an operation.
Defining Message Contracts
To define a message contract for a type (that is, to define the mapping between the type and a
SOAP envelope), apply the MessageContractAttribute to the type. Then apply the
MessageHeaderAttribute to those members of the type you want to make into SOAP headers,
and apply the MessageBodyMemberAttribute to those members you want to make into parts of
the SOAP body of the message.
The following codes provides an example of using a message contract.
C#
Resource Links for 70-513 WCF Certification Exam
77
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
[MessageContract]
publicclass BankingTransaction
{
[MessageHeader] public Operation operation;
[MessageHeader] public DateTime transactionDate;
[MessageBodyMember] private Account sourceAccount;
[MessageBodyMember] private Account targetAccount;
[MessageBodyMember] publicint amount;
}
When using this type as an operation parameter, a SOAP envelope is generated with extra
headers called operation and transactionDate, which contain the contents of the operation and
transactionDate fields. The SOAP body consists of a wrapper element containing elements called
sourceAccount and targetAccount, of the Account data contract type and the amount of the integer type.
You can apply the MessageHeaderAttribute and MessageBodyMemberAttribute to all fields,
properties, and events, regardless of whether they are public, private, protected, or internal.
Note:
KnownTypeAttribute attributes are ignored in message contracts. If a KnownTypeAttribute is required,
place it on the operation that is using the message contract in question.
Using Custom Types Inside Message Contracts
Each individual message header and message body part is serialized (turned into XML) using the
chosen serialization engine for the service contract where the message is used. The default
serialization engine, the XmlFormatter, can handle any type that has a data contract, either
explicitly (by having the System.Runtime.Serialization.DataContractAttribute) or implicitly (by
being a primitive type, having the System.SerializableAttribute, and so on). For more
information, see Using Data Contracts.In the preceding example, the Operation and
BankingTransactionData types must have a data contract, and transactionDate is serializable because
DateTime is a primitive (and so has an implicit data contract).However, it is possible to switch to
a different serialization engine, the XmlSerializer. If you make such a switch, you should ensure
that all of the types used for message headers and body parts are serializable using the
XmlSerializer.
Using Arrays Inside Message Contracts
Resource Links for 70-513 WCF Certification Exam
78
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
You can use arrays of repeating elements in message contracts in two ways.The first is to use a
MessageHeaderAttribute or a MessageBodyMemberAttribute directly on the array. In this
case, the entire array is serialized as one element (that is, one header or one body part) with
multiple child elements. Consider the class in the following example.
C#
[MessageContract]
publicclass BankingDepositLog
{
[MessageHeader] publicint numRecords
[MessageHeader] public DepositRecord records[];
[MessageHeader] publicint branchID;
}
This results in SOAP headers is similar to the following.
<BankingDepositLog>
<numRecords>3</numRecords>
<records>
<DepositRecord>Record1</DepositRecord>
<DepositRecord>Record2</DepositRecord>
<DepositRecord>Record3</DepositRecord>
</records>
<branchID>20643</branchID>
</BankingDepositLog>
An alternative to this is to use the MessageHeaderArrayAttribute. In this case, each array
element is serialized independently and so that each array element has one header, similar to the
following.
<numRecords>3</numRecords>
<records>Record1</records>
<records>Record2</records>
<records>Record3</records>
<branchID>20643</branchID>
The default name for array entries is the name of the member to which the
MessageHeaderArrayAttribute attributes is applied.The MessageHeaderArrayAttribute
attribute inherits from the MessageHeaderAttribute. It has the same set of features as the non-
array attributes, for example, it is possible to set the order, name, and namespace for an array of
Resource Links for 70-513 WCF Certification Exam
79
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
headers in the same way you set it for a single header. When you use the Order property on an
array, it applies to the entire array.You can apply the MessageHeaderArrayAttribute only to
arrays, not collections.
Using Byte Arrays in Message Contracts
Byte arrays, when used with the non-array attributes (MessageBodyMemberAttribute and
MessageHeaderAttribute), are not treated as arrays but as a special primitive type represented
as Base64-encoded data in the resulting XML.When you use byte arrays with the array attribute
MessageHeaderArrayAttribute, the results depend on the serializer in use. With the default
serializer, the array is represented as an individual entry for each byte. However, when the
XmlSerializer is selected, (using the XmlSerializerFormatAttribute on the service contract), byte
arrays are treated as Base64 data regardless of whether the array or non-array attributes are used.
Signing and Encrypting Parts of the Message
A message contract can indicate whether the headers and/or body of the message should be
digitally signed and encrypted.This is done by setting the
System.ServiceModel.MessageContractMemberAttribute.ProtectionLevel property on the
MessageHeaderAttribute and MessageBodyMemberAttribute attributes. The property is an
enumeration of the System.Net.Security.ProtectionLevel type and can be set to None (no
encryption or signature), Sign (digital signature only), or EncryptAndSign (both encryption and a
digital signature). The default is EncryptAndSign.For these security features to work, you must
properly configure the binding and behaviors. If you use these security features without the
proper configuration (for example, attempting to sign a message without supplying your
credentials), an exception is thrown at validation time.For message headers, the protection level
is determined individually for each header.For message body parts, the protection level can be
thought of as the "minimum protection level." The body has only one protection level, regardless
of the number of body parts. The protection level of the body is determined by the highest
ProtectionLevel property setting of all the body parts. However, you should set the protection
level of each body part to the actual minimum protection level required.Consider the class in the
following code example.
C#
[MessageContract]
Resource Links for 70-513 WCF Certification Exam
80
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
publicclass PatientRecord
{
[MessageHeader(ProtectionLevel=None)] publicint recordID;
[MessageHeader(ProtectionLevel=Sign)] publicstring patientName;
[MessageHeader(ProtectionLevel=EncryptAndSign)] publicstring SSN;
[MessageBodyMember(ProtectionLevel=None)] publicstring comments;
[MessageBodyMember(ProtectionLevel=Sign)] publicstring diagnosis;
[MessageBodyMember(ProtectionLevel=EncryptAndSign)] publicstring medicalHistory;
}
In this example, the recordID header is not protected, patientName is signed, and SSN is encrypted
and signed. At least one body part, medicalHistory, has EncryptAndSign applied, and thus the
entire message body is encrypted and signed, even though the comments and diagnosis body
parts specify lower protection levels.
Controlling Header and Body Part Names and Namespaces
In the SOAP representation of a message contract, each header and body part maps to an XML
element that has a name and a namespace.By default, the namespace is the same as the
namespace of the service contract that the message is participating in, and the name is
determined by the member name to which the MessageHeaderAttribute or the
MessageBodyMemberAttribute attributes are applied.You can change these defaults by
manipulating the System.ServiceModel.MessageContractMemberAttribute.Name and
System.ServiceModel.MessageContractMemberAttribute.Namespace (on the parent class of the
MessageHeaderAttribute and MessageBodyMemberAttribute attributes).Consider the class
in the following code example.
C#
[MessageContract]
publicclass BankingTransaction
{
[MessageHeader] public Operation operation;
[MessageHeader(Namespace="http://schemas.contoso.com/auditing/2005")] publicbool IsAudited;
[MessageBodyMember(Name="transactionData")] public BankingTransactionData theData;
}
Resource Links for 70-513 WCF Certification Exam
81
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
In this example, the IsAudited header is in the namespace specified in the code, and the body part
that represents the theData member is represented by an XML element with the name
transactionData.
Controlling Whether the SOAP Body Parts Are Wrapped
By default, the SOAP body parts are serialized inside a wrapped element. For example, the
following code shows the HelloGreetingMessage wrapper element generated from the name of the
MessageContractAttribute type in the message contract for the HelloGreetingMessage message.
C#
[MessageContract]
publicclass HelloGreetingMessage
{
privatestring localGreeting;
[MessageBodyMember(Name = "Salutations", Namespace = http://www.examples.com )]
publicstring Greeting
{
get { return localGreeting; }
set { localGreeting = value; }
}
}
/* The following is the request message, edited for clarity.
<s:Envelope>
<s:Header>
<!-- Note: Some header content has been removed for clarity.
<a:Action>http://GreetingMessage/Action</a:Action>
<a:To s:mustUnderstand="1"></a:To>
</s:Header>
<s:Body u:Id="_0" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<HelloGreetingMessage xmlns="Microsoft.WCF.Documentation">
<Salutations xmlns="http://www.examples.com">Hello.</Salutations>
</HelloGreetingMessage>
</s:Body>
</s:Envelope> */
Resource Links for 70-513 WCF Certification Exam
82
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
To suppress the wrapper element, set the IsWrapped property to false. To control the name and
the namespace of the wrapper element, use the WrapperName and WrapperNamespace
properties.
Note:
Having more than one message body part in messages that are not wrapped is not compliant with WS-I
Basic Profile 1.1 and is not recommended when designing new message contracts. However, it may be
necessary to have more than one unwrapped message body part in certain specific interoperability
scenarios. If you are going to transmit more than one piece of data in a message body, it is recommended
to use the default (wrapped) mode. Having more than one message header in unwrapped messages is
completely acceptable.
SOAP Action
SOAP and related Web services standards define a property called Action that can be present for
every SOAP message sent. The operation's
System.ServiceModel.OperationContractAttribute.Action and
System.ServiceModel.OperationContractAttribute.ReplyAction properties control the value of
this property.
SOAP Header Attributes
The SOAP standard defines the following attributes that may exist on a header:
Actor/Role (Actor in SOAP 1.1, Role in SOAP 1.2)
MustUnderstand
Relay
The Actor or Role attribute specifies the Uniform Resource Identifier (URI) of the node for
which a given header is intended. The MustUnderstand attribute specifies whether the node
processing the header must understand it. The Relay attribute specifies whether the header is to
be relayed to downstream nodes. WCF does not perform any processing of these attributes on
incoming messages, except for the MustUnderstand attribute, as specified in the "Message
Contract Versioning" section later in this topic. However, it allows you to read and write these
attributes as necessary, as in the following description.When sending a message, these attributes
are not emitted by default. You can change this in two ways. First, you may statically set the
attributes to any desired values by changing the
Resource Links for 70-513 WCF Certification Exam
83
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
System.ServiceModel.MessageHeaderAttribute.Actor,
System.ServiceModel.MessageHeaderAttribute.MustUnderstand, and
System.ServiceModel.MessageHeaderAttribute.Relay properties, as shown in the following code
example. (Note that there is no Role property; setting the Actor property emits the Role attribute
if you are using SOAP 1.2).
C#
[MessageContract]
publicclass BankingTransaction
{
[MessageHeader(Actor="http://auditingservice.contoso.com", MustUnderstand=true)] publicbool IsAudited;
[MessageHeader] public Operation operation;
[MessageBodyMember] public BankingTransactionData theData;
}
The second way to control these attributes is dynamically, through code. You can achieve this by
wrapping the desired header type in the MessageHeader type (be sure not to confuse this type
with the non-generic version) and by using the type together with the MessageHeaderAttribute.
Then, you can use properties on the MessageHeader to set the SOAP attributes, as shown in the
following code example.
C#
[MessageContract]
publicclass BankingTransaction
{
[MessageHeader] public MessageHeader<bool> IsAudited;
[MessageHeader] public Operation operation;
[MessageBodyMember] public BankingTransactionData theData;
}
// application code:
BankingTransaction bt = new BankingTransaction();
bt.IsAudited = new MessageHeader<bool>();
bt.IsAudited.Content = false; // Set IsAudited header value to "false"
bt.IsAudited.Actor="http://auditingservice.contoso.com";
bt.IsAudited.MustUnderstand=true;
Resource Links for 70-513 WCF Certification Exam
84
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
If you use both the dynamic and the static control mechanisms, the static settings are used as a
default but can later be overridden by using the dynamic mechanism, as shown in the following
code.
[C#]
[MessageHeader(MustUnderstand=true)] public MessageHeader<Person> documentApprover;
// later on in the code:
BankingTransaction bt = new BankingTransaction();
bt.documentApprover = new MessageHeader<Person>();
bt.documentApprover.MustUnderstand = false; // override the static default of 'true'
Creating repeated headers with dynamic attribute control is allowed, as shown in the following
code.
C#
[MessageHeaderArray] public MessageHeader<Person> documentApprovers[];
On the receiving side, reading these SOAP attributes can only be done if the MessageHeader
class is used for the header in the type. Examine the Actor, Relay, or MustUnderstand
properties of a header of the MessageHeader type to discover the attribute settings on the
received message.When a message is received and then sent back, the SOAP attribute settings
only go round-trip for headers of the MessageHeader type.
Order of SOAP Body Parts
In some circumstances, you may need to control the order of the body parts. The order of the
body elements is alphabetical by default, but can be controlled by the
System.ServiceModel.MessageBodyMemberAttribute.Order property. This property has the
same semantics as the System.Runtime.Serialization.DataMemberAttribute.Order property,
except for the behavior in inheritance scenarios (in message contracts, base type body members
are not sorted before the derived type body members). For more information, see Data Member
Order. In the following example, amount would normally come first because it is
firstalphabetically. However, the Order property puts it into the third position.
C#
[MessageContract]
publicclass BankingTransaction
{
[MessageHeader] public Operation operation;
Resource Links for 70-513 WCF Certification Exam
85
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
[MessageBodyMember(Order=1)] public Account sourceAccount;
[MessageBodyMember(Order=2)] public Account targetAccount;
[MessageBodyMember(Order=3)] publicint amount;
}
Message Contract Versioning
Occasionally, you may need to change message contracts. For example, a new version of your
application may add an extra header to a message. Then, when sending from the new version to
the old, the system must deal with an extra header, as well as a missing header when going in the
other direction.
The following rules apply for versioning headers:
WCF does not object to the missing headersthe corresponding members are left at their default values.
WCF also ignores unexpected extra headers. The one exception to this rule is if the extra header has a
MustUnderstand attribute set to true in the incoming SOAP messagein this case, an exception is
thrown because a header that must be understood cannot be processed.Message bodies have similar
versioning rulesboth missing and additional message body parts are ignored.
Inheritance Considerations
A message contract type can inherit from another type, as long as the base type also has a
message contract. When creating or accessing a message using a message contract type that
inherits from other message contract types, the following rules apply:
All of the message headers in the inheritance hierarchy are collected together to form the full set of
headers for the message.
All of the message body parts in the inheritance hierarchy are collected together to form the full message
body. The body parts are ordered according to the usual ordering rules (by
System.ServiceModel.MessageBodyMemberAttribute.Order property and then alphabetical), with no
relevance to their place in the inheritance hierarchy. Using message contract inheritance where message
body parts occur at multiple levels of the inheritance tree is strongly discouraged. If a base class and a
derived class define a header or a body part with the same name, the member from the base-most class is
used to store the value of that header or body part.Consider the classes in the following code example.
C#
[MessageContract]
publicclass PersonRecord
{
Resource Links for 70-513 WCF Certification Exam
86
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
[MessageHeader(Name="ID")] publicint personID;
[MessageBodyMember] publicstring patientName;
}
[MessageContract]
publicclass PatientRecord : PersonRecord
{
[MessageHeader(Name="ID")] publicint patientID;
[MessageBodyMember] publicstring diagnosis;
}
The PatientRecord class describes a message with one header called ID. The header corresponds to
the personID and not the patientID member, because the base-most member is chosen. Thus, the
patientID field is useless in this case. The body of the message contains the diagnosis element
followed by the patientName element, because that is the alphabetical order. Notice that the
example shows a pattern that is strongly discouraged: both the base and the derived message
contracts have message body parts.
WSDL Considerations
When generating a Web Services Description Language (WSDL) contract from a service that
uses message contracts, it is important to remember that not all message contract features are
reflected in the resulting WSDL. Consider the following points:
WSDL cannot express the concept of an array of headers. When creating messages with an array of
headers using the MessageHeaderArrayAttribute, the resulting WSDL reflects only one header instead
of the array.
The resulting WSDL document may not reflect some protection-level information.
The message type generated in the WSDL has the same name as the class name of the message contract
type.
When using the same message contract in multiple operations, multiple message types are generated in
the WSDL document. The names are made unique by adding the numbers "2", "3", and so on, for
subsequent uses. When importing back the WSDL, multiple message contract types are created and are
identical except for their names.
SOAP Encoding Considerations
WCF allows you to use the legacy SOAP encoding style of XML, however, its use is not
recommended. When using this style (by setting the Use property to Encoded on the
Resource Links for 70-513 WCF Certification Exam
87
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
System.ServiceModel.XmlSerializerFormatAttribute applied to the service contract), the
following additional considerations apply:
The message headers are not supported; this means that the attribute MessageHeaderAttribute and the
array attribute MessageHeaderArrayAttribute are incompatible with SOAP encoding.
If the message contract is not wrapped, that is, if the property IsWrapped is set to false, the message
contract can have only one body part.
The name of the wrapper element for the request message contract must match the operation name. Use
the WrapperName property of the message contract for this.
The name of the wrapper element for the response message contract must be the same as the name of the
operation suffixed by 'Response'. Use the WrapperName property of the message contract for this.
SOAP encoding preserves object references. For example, consider the following code.
C#
[MessageContract(WrapperName="updateChangeRecord")]
publicclass ChangeRecordRequest
{
[MessageBodyMember] Person changedBy;
[MessageBodyMember] Person changedFrom;
[MessageBodyMember] Person changedTo;
}
[MessageContract(WrapperName="updateChangeRecordResponse")]
publicclass ChangeRecordResponse
{
[MessageBodyMember] Person changedBy;
[MessageBodyMember] Person changedFrom;
[MessageBodyMember] Person changedTo;
}
// application code:
ChangeRecordRequest cr = new ChangeRecordRequest();
Person p = new Person("John Doe");
cr.changedBy=p;
cr.changedFrom=p;
cr.changedTo=p;
After serializing the message using SOAP encoding, changedFrom and changedTo do not contain
their own copies of p, but instead point to the copy inside the changedBy element.
Resource Links for 70-513 WCF Certification Exam
88
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Performance Considerations
Every message header and message body part is serialized independently of the others.
Therefore, the same namespaces can be declared again for each header and body part. To
improve performance, especially in terms of the size of the message on the wire, consolidate
multiple headers and body parts into a single header or body part. For example, instead of the
following code:
C#
[MessageContract]
publicclass BankingTransaction
{
[MessageHeader] public Operation operation;
[MessageBodyMember] public Account sourceAccount;
[MessageBodyMember] public Account targetAccount;
[MessageBodyMember] publicint amount;
}
Use this code.
C#
[MessageContract]
publicclass BankingTransaction
{
[MessageHeader] public Operation operation;
[MessageBodyMember] public OperationDetails details;
}
[DataContract]
publicclass OperationDetails
{
[DataMember] public Account sourceAccount;
[DataMember] public Account targetAccount;
[DataMember] publicint amount;
}
Event-based Asynchronous and Message Contracts
The design guidelines for the event-based asynchronous model state that if more than one value
is returned, one value is returned as the Result property and the others are returned as properties
on the EventArgs object. One result of this is that if a client imports metadata using the event-
Resource Links for 70-513 WCF Certification Exam
89
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
based asynchronous command options and the operation returns more than one value, the default
EventArgs object returns one value as the Result property and the remainder are properties of
the EventArgs object.
If you want to receive the message object as the Result property and have the returned values as
properties on that object, use the /messageContract command option. This generates a signature
that returns the response message as the Result property on the EventArgs object. All internal
return values are then properties of the response message object.Implement generic message
handling.This objective may include but is not limited to: creating a catch-all contract; reading
and writing messages; working with properties; working with headersThis objective does not
include: inheriting from Message class; using BodyWriter; creating Fault messages Implement
RESTful services.This objective may include but is not limited to: accessing HTTP context;
WebGet/WebInvoke, UriTemplates; JSON/POX
WCF Web HTTP Programming Model
Overview
The Windows Communication Foundation (WCF) WEB HTTP programming model provides
the basic elements required to build WEB HTTP services with WCF. WCF WEB HTTP services
are designed to be accessed by the widest range of possible clients, including Web browsers and
have the following unique requirements:
URIs and URI Processing URIs play a central role in the design of WEB HTTP services. The
WCF WEB HTTP programming model uses the UriTemplate and UriTemplateTable classes to
provide URI processing capabilities.
Support for GET and POST operations WEB HTTP services make use of the GET verb for data
retrieval, in addition to various invoke verbs for data modification and remote invocation. The
WCF WEB HTTP programming model uses the WebGetAttribute and WebInvokeAttribute to
associate service operations with both GET and other HTTP verbs like PUT, POST, and
DELETE.
Multiple data formats Web-style services process many kinds of data in addition to SOAP
messages. The WCF WEB HTTP programming model uses the WebHttpBinding and
WebHttpBehavior to support many different data formats including XML documents, JSON data
Resource Links for 70-513 WCF Certification Exam
90
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
object, and streams of binary content such as images, video files, or plain text.The WCF WEB
HTTP programming model extends the reach of WCF to cover Web-style scenarios that include
WEB HTTP services, AJAX and JSON services, and Syndication (ATOM/RSS) feeds. For more
information about AJAX and JSON services, see AJAX Integration and JSON Support. For more
information about Syndication, see WCF Syndication Overview.There are no extra restrictions
on the types of data that can be returned from a WEB HTTP service. Any serializable type can
be returned from an WEB HTTP service operation. Because WEB HTTP service operations can
be invoke by a web browser there is a limitation on what data types can be specified in a URL.
For more information on what types are supported by default see the UriTemplate Query String
Parameters and URLs section below. The default behavior can be changed by providing your
own T:System.ServiceModel.Dispatcher.QueryStringConverter implementation which specifies
how to convert the parameters specified in a URL to the actual parameter type. For more
information, see QueryStringConverter
Caution
Services written with the WCF WEB HTTP programming model do not use SOAP messages.
Because SOAP is not used, the security features provided by WCF cannot be used. You can,
however use transport-based security by hosting your service with HTTPS. For more information
about WCF security, see Security Overview
Caution
Installing the WebDAV extension for IIS can cause Web HTTP services to return an HTTP 405
error as the WebDAV extension attempts to handle all PUT requests. To work around this issue
you can uninstall the WebDAV extension or disable the WebDAV extension for your web site.
For more information, see IIS and WebDav
URI Processing with UriTemplate and UriTemplateTable
URI templates provide an efficient syntax for expressing large sets of structurally similar URIs.
For example, the following template expresses the set of all three-segment URIs that begin with
"a" and end with "c" without regard to the value of the intermediate segment: a/{segment}/c
This template describes URIs like the following:
a/x/c
a/y/c
Resource Links for 70-513 WCF Certification Exam
91
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
a/z/c
and so on.
In this template, the curly brace notation ("{segment}") indicates a variable segment instead of a
literal value..NET Framework provides an API for working with URI templates called
UriTemplate. UriTemplates allow you to do the following:
You can call one of the Bind methods with a set of parameters to produce a fully-closed URI that
matches the template. This means all variables within the URI template are replaced with actual
values.
You can call Match() with a candidate URI, which uses a template to break up a candidate URI
into its constituent parts and returns a dictionary that contains the different parts of the URI
labeled according to the variables in the template.
Bind () and Match() are inverses so that you can call Match( Bind( x ) ) and come back with the
same environment you started with.
There are many times (especially on the server, where dispatching a request to a service
operation based on the URI is necessary) that you want to keep track of a set of UriTemplate
objects in a data structure that can independently address each of the contained templates.
UriTemplateTable represents a set of URI templates and selects the best match given a set of
templates and a candidate URI. This is not affiliated with any particular networking stack (WCF
included) so you can use it wherever necessary. The WCF Service Model makes use of
UriTemplate and UriTemplateTable to associate service operations with a set of URIs described
by a UriTemplate. A service operation is associated with a UriTemplate, using either the
WebGetAttribute or the WebInvokeAttribute. For more information about UriTemplate and
UriTemplateTable, see UriTemplate and UriTemplateTableWebGet and WebInvoke Attributes
WCF WEB HTTP services make use of retrieval verbs (for example HTTP GET) in addition to
various invoke verbs (for example HTTP POST, PUT, and DELETE). The WCF WEB HTTP
programming model allows service developers to control the both the URI template and verb
associated with their service operations with the WebGetAttribute and WebInvokeAttribute. The
WebGetAttribute and the WebInvokeAttribute allow you to control how individual operations
get bound to URIs and the HTTP methods associated with those URIs. For example, adding
WebGetAttribute and WebInvokeAttribute in the following code.
[ServiceContract]
Resource Links for 70-513 WCF Certification Exam
92
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
interface ICustomer
{
//"View It"
[WebGet]
Customer GetCustomer():
//"Do It"
[WebInvoke]
Customer UpdateCustomerName( string id, string newName );
}
The preceding code allows you to make the following HTTP requests.
GET /GetCustomer
POST /UpdateCustomerName
WebInvokeAttribute defaults to POST but you can use it for other verbs too.
[ServiceContract]
interface ICustomer
{
//"View It" -> HTTP GET
[WebGet( UriTemplate="customers/{id}" )]
Customer GetCustomer( string id ):
//"Do It -> HTTP PUT
[WebInvoke( UriTemplate="customers/{id}", Method="PUT" )]
Customer UpdateCustomer( string id, Customer newCustomer );
}
To see a complete sample of a WCF service that uses the WCF WEB HTTP programming
model, see How to: Create a Basic WCF Web HTTP Service
UriTemplate Query String Parameters and URLsWeb-style services can be called from a Web browser by
typing a URL that is associated with a service operation. These service operations may take query string
parameters that must be specified in a string form within the URL. The following table shows the types
that can be passed within a URL and the format used.
Type Format
Byte 0 - 255
SByte -128 - 127
Int16 -32768 - 32767
Resource Links for 70-513 WCF Certification Exam
93
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Int32 -2,147,483,648 - 2,147,483,647
Int64 -9,223,372,036,854,775,808 - 9,223,372,036,854,775,807
UInt16 0 - 65535
UInt32 0 - 4,294,967,295
UInt64 0 - 18,446,744,073,709,551,615
Single -3.402823e38 - 3.402823e38 (exponent notation is not required)
Double
-1.79769313486232e308 - 1.79769313486232e308 (exponent
notation is not required)
Char Any single character
Decimal Any decimal in standard notation (no exponent)
Boolean True or False (case insensitive)
String Any string (null string is not supported and no escaping is done)
DateTime
MM/DD/YYYY
MM/DD/YYYY HH:MM:SS [AM|PM]
Month Day Year
Month Day Year HH:MM:SS [AM|PM]
TimeSpan
DD.HH:MM:SS
Where DD = Days, HH = Hours, MM = minutes, SS = Seconds
Guid
A GUID, for example:
936DA01F-9ABD-4d9d-80C7-02AF85C822A8
DateTimeOffset
MM/DD/YYYY HH:MM:SS MM:SS
Where DD = Days, HH = Hours, MM = minutes, SS = Seconds
Enumerations
The enumeration value for example, which defines the enumeration
as shown in the following code.
public enum Days{ Sunday, Monday, Tuesday, Wednesday,
Thursday, Friday, Saturday };
Any of the individual enumeration values (or their corresponding
integer values) may be specified in the query string.
Resource Links for 70-513 WCF Certification Exam
94
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Types that have a
TypeConverterAttribute
that can convert the type
to and from a string
representation.
Depends on the Type Converter.
Formats and the WCF WEB HTTP Programming Model
The WCF WEB HTTP programming model has new features to work with many different data
formats. At the binding layer, the WebHttpBinding can read and write the following different
kinds of data:
XML
JSON
Opaque binary streams
This means the WCF WEB HTTP programming model can handle any type of data but, you may
be programming against Stream. .NET Framework 3.5 provides support for JSON data (AJAX)
as well as Syndication feeds (including ATOM and RSS). For more information about these
features, see WCF Web HTTP FormattingWCF Syndication Overview and AJAX Integration
and JSON Support. WCF WEB HTTP Programming Model and SecurityBecause the WCF WEB
HTTP programming model does not support the WS-* protocols, the only way to secure a WCF
WEB HTTP service is to expose the service over HTTPS using SSL. For more information about
setting up SSL with IIS 7.0, see How to implement SSL in IISTroubleshooting the WCF WEB
HTTP Programming ModelWhen calling WCF WEB HTTP services using a ChannelFactory to
create a channel, the WebHttpBehavior uses the EndpointAddress set in the configuration file
even if a different EndpointAddress is passed to the ChannelFactory.
WCF Web HTTP Programming Object
Model
The WCF WEB HTTP Programming Model allows developers to expose Windows
Communication Foundation (WCF) Web services through basic HTTP requests without
Resource Links for 70-513 WCF Certification Exam
95
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
requiring SOAP. The WCF WEB HTTP Programming Model is built on top of the existing WCF
extensibility model. It defines the following classes:
Programming Model:
AspNetCacheProfileAttribute
WebGetAttribute
WebInvokeAttribute
WebServiceHost
Channels and Dispatcher Infrastructure:
WebHttpBinding
WebHttpBehavior
Utility Classes and Extensibility Points:
UriTemplate
UriTemplateTable
QueryStringConverter
WebHttpDispatchOperationSelector
AspNetCacheProfileAttribute
The AspNetCacheProfileAttribute, when applied to a service operation, indicates the ASP.NET
output cache profile in the configuration file that should be used by to cache responses from the
operation in the ASP .NET Output Cache. This property takes only one parameter, the cache
profile name that specifies the cache settings in the configuration file.
WebGetAttribute
The WebGetAttribute attribute is used to mark a service operation as one that responds to HTTP
GET requests. It is a passive operation behavior (the IOperationBehavior methods do nothing)
that adds metadata to the operation description. Applying the WebGetAttribute has no effect
unless a behavior that looks for this metadata in the operation description (specifically, the
WebHttpBehavior) is added to the service's behavior collection. The WebGetAttribute attribute
takes the optional parameters shown in the following table.
Parameter Description
BodyStyle
Controls whether to wrap requests and responses sent to and received from the
service operation the attribute is applied to.
Resource Links for 70-513 WCF Certification Exam
96
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
RequestFormat Controls how request messages are formatted.
ResponseFormat Controls how response messages are formatted.
UriTemplate
Specifies the URI template that controls what HTTP requests get mapped to the
service operation the attribute is applied to.
WebHttpBinding
The WebHttpBinding class incorporates support for XML, JSON, and raw binary data using the
WebMessageEncodingBindingElement. It is composed of an HttpsTransportBindingElement,
HttpTransportBindingElement and a WebHttpSecurity object. The WebHttpBinding is designed
to be used in conjunction with the WebHttpBehavior.
WebInvokeAttribute
The WebInvokeAttribute attribute is similar to the WebGetAttribute, but it is used to mark a
service operation as one that responds to HTTP requests other than GET. It is a passive operation
behavior (the IOperationBehavior methods do nothing) that adds metadata to the operation
description. Applying the WebInvokeAttribute has no effect unless a behavior that looks for this
metadata in the operation description (specifically, the WebHttpBehavior) is added to the
service's behavior collection.
The WebInvokeAttribute attribute takes the optional parameters shown in the following table.
Parameter Description
BodyStyle
Controls whether to wrap requests and responses sent to and received from the
service operation the attribute is applied to.
Method Specifies the HTTP method the service operation is mapped to.
RequestFormat Controls how request messages are formatted.
ResponseFormat Controls how response messages are formatted.
UriTemplate
Specifies the URI template that controls what GET requests get mapped to the
service operation the attribute is applied to.
UriTemplate
The UriTemplate class allows you to define a set of structurally similar URIs. Templates are
composed of two parts, a path and a query. A path consists of a series of segments delimited by a
slash (/). Each segment can have a literal value, a variable value (written within curly braces [{
Resource Links for 70-513 WCF Certification Exam
97
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
}], constrained to match the contents of exactly one segment), or a wildcard (written as an
asterisk [*], which matches "the rest of the path"), which must appear at the end of the path. The
query expression can be omitted entirely. If present, it specifies an unordered series of
name/value pairs. Elements of the query expression can be either literal pairs (?x=2) or variable
pairs (?x={value}). Unpaired values are not permitted. UriTemplate is used internally by the
WCF WEB HTTP Programming Model to map specific URIs or groups of URIs to service
operations.
UriTemplateTable
The UriTemplateTable class represents an associative set of UriTemplate objects bound to an
object of the developer's choosing. It lets you match candidate Uniform Resource Identifiers
(URIs) against the templates in the set and retrieve the data associated with the matching
templates. UriTemplateTable is used internally by the WCF WEB HTTP Programming Model to
map specific URIs or groups of URIs to service operations.
WebServiceHost
WebServiceHost extends the ServiceHost to make it easier to host a non-SOAP Web-style
service. If WebServiceHost finds no endpoints in the service description, it automatically creates
a default endpoint at the service's base address. When creating a default HTTP endpoint, the
WebServiceHost also disables the HTTP Help page and the Web Services Description Language
(WSDL) GET functionality so the metadata endpoint does not interfere with the default HTTP
endpoint. WebServiceHost also ensures that all endpoints that use WebHttpBinding have the
required WebHttpBehavior attached. Finally, WebServiceHost automatically configures the
endpoint's binding to work with the associated Internet Information Services (IIS) security
settings when used in a secure virtual directory.
WebServiceHostFactory
The WebServiceHostFactory class is used to dynamically create a WebServiceHost when a
service is hosted under Internet Information Services (IIS) or Windows Process Activation
Service (WAS). Unlike a self-hosted service where the hosting application instantiates the
WebServiceHost, services hosted under IIS or WAS use this class to create the WebServiceHost
for the service. The CreateServiceHost(Type, Uri[]) method is called when a incoming request
for the service is received.
WebHttpBehavior
Resource Links for 70-513 WCF Certification Exam
98
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The WebHttpBehavior class supplies the necessary formatters, operation selectors, and so on,
required for Web-style service support at the Service Model layer. This is implemented as an
endpoint behavior (used in conjunction with the WebHttpBinding) and allows formatters and
operation selectors to be specified for each endpoint, which enables the same service
implementation to expose both SOAP and POX endpoints.
Extending WebHttpBehavior
WebHttpBehavior is extensible by using a number of virtual methods:
GetOperationSelector(ServiceEndpoint), GetReplyClientFormatter(OperationDescription,
ServiceEndpoint), GetRequestClientFormatter(OperationDescription, ServiceEndpoint),
GetReplyDispatchFormatter(OperationDescription, ServiceEndpoint), and
GetRequestDispatchFormatter(OperationDescription, ServiceEndpoint). Developers can derive a
class from WebHttpBehavior and override these methods to customize the default behavior.
The WebScriptEnablingBehavior is an example of extending WebHttpBehavior.
WebScriptEnablingBehavior enables Windows Communication Foundation (WCF) endpoints to
receive HTTP requests from a browser-based ASP.NET AJAX client. The AJAX Service Using
HTTP POST is an example of using this extensibility point.
Caution
When using the WebScriptEnablingBehavior, UriTemplate are not supported within
WebGetAttribute or WebInvokeAttribute attributes.
WebHttpDispatchOperationSelector
The WebHttpDispatchOperationSelector class uses UriTemplate and UriTemplateTable classes
to dispatch calls to service operations.
Compatibility
The WCF WEB HTTP Programming Model does not use SOAP-based messages and therefore
does not support the WS-* protocols. You can however, expose the same contract by two
different endpoint: one using SOAP and the other not using SOAP. See How to: Expose a
Contract to SOAP and Web Clients for an example.
Security
Because the WCF WEB HTTP Programming Model does not support the WS-* protocols the
only way to secure a Web service built on the WCF WEB HTTP Programming Model is to
Resource Links for 70-513 WCF Certification Exam
99
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
expose your service using SSL. For more information about setting up SSL with IIS 7.0 see How
to implement SSL in IIS
How to: Create a Basic WCF Web HTTP
Service
Windows Communication Foundation (WCF) allows you to create a service that exposes a Web
endpoint. Web endpoints send data by XML or JSON, there is no SOAP envelope. This topic
demonstrates how to expose such an endpoint.
Note
The only way to secure a Web endpoint is to expose it through HTTPS, using transport security.
When using message-based security, security information is usually placed in SOAP headers and
because the messages sent to non-SOAP endpoints contain no SOAP envelope, there is nowhere
to place the security information and you must rely on transport security.
To create a Web endpoint
1. Define a service contract using an interface marked with the ServiceContractAttribute,
WebInvokeAttribute and the WebGetAttribute attributes.
C#
[ServiceContract]
publicinterface IService
{
[OperationContract]
[WebGet]
string EchoWithGet(string s);
[OperationContract]
[WebInvoke]
string EchoWithPost(string s);
}


Note
By default, WebInvokeAttribute maps POST calls to the operation. You can, however, specify the
Resource Links for 70-513 WCF Certification Exam
100
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
HTTP method (for example, HEAD, PUT, or DELETE) to map to the operation by specifying a
"method=" parameter. WebGetAttribute does not have a "method=" parameter and only maps GET
calls to the service operation.
2. Implement the service contract.
C#
publicclass Service : IService
{
publicstring EchoWithGet(string s)
{
return"You said " + s;
}
publicstring EchoWithPost(string s)
{
return"You said " + s;
}
}
To host the service
1. Create a WebServiceHost object.
C#
WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("http://localhost:8000/"));
2. Add a ServiceEndpoint with the WebHttpBehavior.
C#
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
Note
If you do not add an endpoint, WebServiceHost automatically creates a default endpoint.
WebServiceHost also adds WebHttpBehavior and disables the HTTP Help page and the Web
Services Description Language (WSDL) GET functionality so the metadata endpoint does not
interfere with the default HTTP endpoint.Adding a non-SOAP endpoint with a URL of "" causes
unexpected behavior when an attempt is made to call an operation on the endpoint. The reason for
this is the listen URI of the endpoint is the same as the URI for the help page (the page that is
displayed when you browse to the base address of a WCF service).
You can do one of the following actions to prevent this from happening:
Resource Links for 70-513 WCF Certification Exam
101
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
o Always specify a non-blank URI for a non-SOAP endpoint.
o Turn off the help page. This can be done with the following code.
C#
ServiceDebugBehavior sdb = host.Description.Behaviors.Find<ServiceDebugBehavior>();
sdb.HttpHelpPageEnabled = false;
3. Open the service host and wait until the user presses ENTER.
C#
host.Open();
Console.WriteLine("Service is running");
Console.WriteLine("Press enter to quit...");
Console.ReadLine();
host.Close();
This sample demonstrates how to host a Web-Style service with a console application. You can
also host such a service within IIS. To do this, specify the WebServiceHostFactory class in a .svc
file as the following code demonstrates.
<%ServiceHost language=c# Debug="true" Service="Microsoft.Samples.Service"
Factory=System.ServiceModel.Activation.WebServiceHostFactory%>
To call service operations mapped to GET in Internet Explorer
Open Internet Explorer and type "http://localhost:8000/EchoWithGet?s=Hello, world!" and press
ENTER. The URL contains the base address of the service ("http://localhost:8000/"), the relative
address of the endpoint (""), the service operation to call ("EchoWithGet"), and a question mark
followed by a list of named parameters separated by an ampersand (&).
To call service operations in code
1. Create an instance of WebChannelFactory within a using block.
C#
using (ChannelFactory<IService> cf = new ChannelFactory<IService>(new WebHttpBinding(),
"http://localhost:8000"))
2. Add WebHttpBehavior to the endpoint the ChannelFactory calls.
C#
cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
3. Create the channel and call the service.
C#
IService channel = cf.CreateChannel();
Resource Links for 70-513 WCF Certification Exam
102
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
string s;
Console.WriteLine("Calling EchoWithGet via HTTP GET: ");
s = channel.EchoWithGet("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
Console.WriteLine("This can also be accomplished by navigating to");
Console.WriteLine("http://localhost:8000/EchoWithGet?s=Hello, world!");
Console.WriteLine("in a web browser while this sample is running.");
Console.WriteLine("");
Console.WriteLine("Calling EchoWithPost via HTTP POST: ");
s = channel.EchoWithPost("Hello, world");
Console.WriteLine(" Output: {0}", s);
4. Close the WebServiceHost.
C#
host.Close();
ExampleThe following is the full code listing for this example.
C#
// Service.cs
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;
namespace Microsoft.ServiceModel.Samples.BasicWebProgramming
{
[ServiceContract]
publicinterface IService
{
[OperationContract]
[WebGet]
string EchoWithGet(string s);
[OperationContract]
[WebInvoke]
string EchoWithPost(string s);
}
Resource Links for 70-513 WCF Certification Exam
103
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
publicclass Service : IService
{
publicstring EchoWithGet(string s)
{
return"You said " + s;
}
publicstring EchoWithPost(string s)
{
return"You said " + s;
}
}
class Program
{
staticvoid Main(string[] args)
{
WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("http://localhost:8000/"));
try
{
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "");
host.Open();
using (ChannelFactory<IService> cf = new ChannelFactory<IService>(new WebHttpBinding(),
"http://localhost:8000"))
{
cf.Endpoint.Behaviors.Add(new WebHttpBehavior());
IService channel = cf.CreateChannel();
string s;
Console.WriteLine("Calling EchoWithGet via HTTP GET: ");
s = channel.EchoWithGet("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
Console.WriteLine("This can also be accomplished by navigating to");
Console.WriteLine("http://localhost:8000/EchoWithGet?s=Hello, world!");
Console.WriteLine("in a web browser while this sample is running.");
Console.WriteLine("");
Console.WriteLine("Calling EchoWithPost via HTTP POST: ");
s = channel.EchoWithPost("Hello, world");
Console.WriteLine(" Output: {0}", s);
Resource Links for 70-513 WCF Certification Exam
104
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Console.WriteLine("");
}
Console.WriteLine("Press <ENTER> to terminate");
Console.ReadLine();
host.Close();
}
catch (CommunicationException cex)
{
Console.WriteLine("An exception occurred: {0}", cex.Message);
host.Abort();
}
}
}
}
Compiling the Code
When compiling Service.cs reference System.ServiceModel.dll and
System.ServiceModel.Web.dll.
How to: Expose a Contract to SOAP and
Web Clients
By default, Windows Communication Foundation (WCF) makes endpoints available only to
SOAP clients. In How to: Create a Basic WCF Web HTTP Service, an endpoint is made
available to non-SOAP clients. There may be times when you want to make the same contract
available both ways, as a Web endpoint and as a SOAP endpoint. This topic shows an example
of how to do this.
To define the service contract
1. Define a service contract using an interface marked with the ServiceContractAttribute,
WebInvokeAttribute and the WebGetAttribute attributes, as shown in the following code.
C#
[ServiceContract]
publicinterface IService
{
[OperationContract]
Resource Links for 70-513 WCF Certification Exam
105
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
[WebGet]
string EchoWithGet(string s);
[OperationContract]
[WebInvoke]
string EchoWithPost(string s);
}
Note
By default WebInvokeAttribute maps POST calls to the operation. You can, however, specify the
method to map to the operation by specifying a "method=" parameter. WebGetAttribute does not
have a "method=" parameter and only maps GET calls to the service operation.
2. Implement the service contract, as shown in the following code.
C#
publicclass Service : IService
{
publicstring EchoWithGet(string s)
{
return"You said " + s;
}
publicstring EchoWithPost(string s)
{
return"You said " + s;
}
}
To host the service
1. Create a ServiceHost object, as shown in the following code.
C#
ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8000"));
2. Add a ServiceEndpoint with BasicHttpBinding for the SOAP endpoint, as shown in the
following code.
C#
host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
3. Add a ServiceEndpoint with WebHttpBinding for the non-SOAP endpoint and add the
WebHttpBehavior to the endpoint, as shown in the following code.
C#
Resource Links for 70-513 WCF Certification Exam
106
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "Web");
endpoint.Behaviors.Add(new WebHttpBehavior());
4. Call Open() on a ServiceHost instance to open the service host, as shown in the following code.
C#
host.Open();
To call service operations mapped to GET in Internet Explorer
Open Internet Explorer and type "http://localhost:8000/Web/EchoWithGet?s=Hello, world!" and
press ENTER. The URL contains the base address of the service ("http://localhost:8000/"), the
relative address of the endpoint (""), the service operation to call ("EchoWithGet"), and a
question mark followed by a list of named parameters separated by an ampersand (&).
To call service operations on the Web endpoint in code
Create an instance of WebChannelFactory<TChannel> within a using block, as shown in the
following code.
C#
using (WebChannelFactory<IService> wcf = new WebChannelFactory<IService>(new
Uri("http://localhost:8000/Web")))
Note
Close() is automatically called on the channel at the end of the using block.
1. Create the channel and call the service, as shown in the following code.
C#
IService channel = wcf.CreateChannel();
string s;
Console.WriteLine("Calling EchoWithGet by HTTP GET: ");
s = channel.EchoWithGet("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
Console.WriteLine("This can also be accomplished by navigating to");
Console.WriteLine("http://localhost:8000/Web/EchoWithGet?s=Hello, world!");
Console.WriteLine("in a web browser while this sample is running.");
Console.WriteLine("");
Console.WriteLine("Calling EchoWithPost by HTTP POST: ");
s = channel.EchoWithPost("Hello, world");
Console.WriteLine(" Output: {0}", s);
Resource Links for 70-513 WCF Certification Exam
107
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
To call service operations on the SOAP endpoint
1. Create an instance of ChannelFactory within a using block, as shown in the following code.
C#
using (ChannelFactory<IService> scf = new ChannelFactory<IService>(new BasicHttpBinding(),
"http://localhost:8000/Soap"))
2. Create the channel and call the service, as shown in the following code.
C#
IService channel = scf.CreateChannel();
string s;
Console.WriteLine("Calling EchoWithGet on SOAP endpoint: ");
s = channel.EchoWithGet("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
Console.WriteLine("Calling EchoWithPost on SOAP endpoint: ");
s = channel.EchoWithPost("Hello, world");
Console.WriteLine(" Output: {0}", s);
To close the service host
Close the service host, as shown in the following code.
C#
host.Close();
Example
The following is the full code listing for this topic.
C#
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;
namespace Microsoft.ServiceModel.Samples.BasicWebProgramming
{
[ServiceContract]
publicinterface IService
{
[OperationContract]
Resource Links for 70-513 WCF Certification Exam
108
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
[WebGet]
string EchoWithGet(string s);
[OperationContract]
[WebInvoke]
string EchoWithPost(string s);
}
publicclass Service : IService
{
publicstring EchoWithGet(string s)
{
return"You said " + s;
}
publicstring EchoWithPost(string s)
{
return"You said " + s;
}
}
class Program
{
staticvoid Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8000"));
host.AddServiceEndpoint(typeof(IService), new BasicHttpBinding(), "Soap");
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService), new WebHttpBinding(), "Web");
endpoint.Behaviors.Add(new WebHttpBehavior());
try
{
host.Open();
using (WebChannelFactory<IService> wcf = new WebChannelFactory<IService>(new
Uri("http://localhost:8000/Web")))
{
IService channel = wcf.CreateChannel();
string s;
Console.WriteLine("Calling EchoWithGet by HTTP GET: ");
s = channel.EchoWithGet("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
Resource Links for 70-513 WCF Certification Exam
109
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Console.WriteLine("This can also be accomplished by navigating to");
Console.WriteLine("http://localhost:8000/Web/EchoWithGet?s=Hello, world!");
Console.WriteLine("in a web browser while this sample is running.");
Console.WriteLine("");
Console.WriteLine("Calling EchoWithPost by HTTP POST: ");
s = channel.EchoWithPost("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
}
using (ChannelFactory<IService> scf = new ChannelFactory<IService>(new BasicHttpBinding(),
"http://localhost:8000/Soap"))
{
IService channel = scf.CreateChannel();
string s;
Console.WriteLine("Calling EchoWithGet on SOAP endpoint: ");
s = channel.EchoWithGet("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
Console.WriteLine("Calling EchoWithPost on SOAP endpoint: ");
s = channel.EchoWithPost("Hello, world");
Console.WriteLine(" Output: {0}", s);
Console.WriteLine("");
}
Console.WriteLine("Press [Enter] to terminate");
Console.ReadLine();
host.Close();
}
catch (CommunicationException cex)
{
Console.WriteLine("An exception occurred: {0}", cex.Message);
host.Abort();
}
}
}
}
Compiling the Code
Resource Links for 70-513 WCF Certification Exam
110
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
When compiling Service.cs, reference System.ServiceModel.dll and
System.ServiceModel.Web.dll.
UriTemplate and UriTemplateTable
Web developers require the ability to describe the shape and layout of the URIs that their
services respond to. Windows Communication Foundation (WCF) added two new classes to give
developers control over their URIs. UriTemplate and UriTemplateTable form the basis of the
URI-based dispatch engine in WCF. These classes can also be used on their own, allowing
developers to take advantage of templates and the URI mapping mechanism without
implementing a WCF service.
Templates
A template is a way to describe a set of relative URIs. The set of URI templates in the following
table shows how a system that retrieves various types of weather information might be defined.
Data Template
National Forecast weather/national
State Forecast weather/{state}
City Forecast weather/{state}/{city}
Activity Forecast weather/{state}/{city}/{activity}
This table describes a set of structurally similar URIs. Each entry is a URI template. The
segments in curly braces describe variables. The segments not in curly braces describe literal
strings. The WCF template classes allow a developer to take an incoming URI, for example,
"/weather/wa/seattle/cycling", and match it to a template that describes it,
"/weather/{state}/{city}/{activity}".
UriTemplate
UriTemplate is a class that encapsulates a URI template. The constructor takes a string parameter
that defines the template. This string contains the template in the format described in the next
section. The UriTemplate class provides methods that allow you match an incoming URI to a
template, generate a URI from a template, retrieve a collection of variable names used in the
template, determine whether two templates are equivalent, and return the template's string.
Resource Links for 70-513 WCF Certification Exam
111
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Match(Uri, Uri) takes a base address and a candidate URI and attempts to match the URI to the
template. If the match is successful, a UriTemplateMatch instance is returned. The
UriTemplateMatch object contains a base URI, the candidate URI, a name/value collection of the
query parameters, an array of the relative path segments, a name/value collection of variables
that were matched, the UriTemplate instance used to perform the match, a string that contains
any unmatched portion of the candidate URI (used when the template has a wildcard), and an
object that is associated with the template.
Note
The UriTemplate class ignores the scheme and port number when matching a candidate URI to a
template.
There are two methods that allow you to generate a URI from a template, BindByName(Uri,
NameValueCollection) and BindByPosition(Uri, String[]). BindByName(Uri,
NameValueCollection) takes a base address and a name/value collection of parameters. These
parameters are substituted for variables when the template is bound. BindByPosition(Uri,
String[]) takes the name/value pairs and substitutes them left to right.
ToString() returns the template string.
The PathSegmentVariableNames property contains a collection of the names of the variables
used within path segments in the template string.
IsEquivalentTo(UriTemplate) takes a UriTemplate as a parameter and returns a Boolean value
that specifies whether the two templates are equivalent. For more information, see the Template
Equivalence section later in this topic.
UriTemplate is designed to work with any URI scheme that conforms to the HTTP URI
grammar. The following are examples of supported URI schemes.
http://
https://
net.tcp://
net.pipe://
sb://
Schemes like file:// and urn:// do not conform to the HTTP URI grammar and cause
unpredictable results when used with URI templates.
Resource Links for 70-513 WCF Certification Exam
112
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Template String Syntax
A template has three parts: a path, an optional query, and an optional fragment. For an example,
see the following template:
"/weather/{state}/{city}?forecast={length)#frag1
The path consists of "/weather/{state}/{city}", the query consists of "?forecast={length}, and the
fragment consists of "#frag1".
Leading and trailing slashes are optional in the path expression. Both the query and fragment
expressions can be omitted entirely. A path consists of a series of segments delimited by '/', each
segment can have a literal value, a variable name (written in {curly braces}), or a wildcard
(written as '*'). In the previous template the "\weather\ segment is a literal value while "{state}"
and "{city}" are variables. Variables take their name from the contents of their curly braces and
they can later be replaced with a concrete value to create a closed URI. The wildcard is optional,
but can only appear at the end of the URI, where it logically matches the rest of the path.
The query expression, if present, specifies a series of unordered name/value pairs delimited by
'&'. Elements of the query expression can either be literal pairs (x=2) or a variable pair
(x={var}). Only the right side of the query can have a variable expression. ({someName} =
{someValue} is not allowed. Unpaired values (?x) are not permitted. There is no difference
between an empty query expression and a query expression consisting of just a single '?' (both
mean "any query").
The fragment expression can consist of a literal value, no variables are allowed.
All template variable names within a template string must be unique. Template variable names
are case-insensitive.
Examples of valid template strings:
""
"/shoe"
"/shoe/*"
"{shoe}/boat"
{shoe}/{boat}/bed/{quilt}
shoe/{boat}
shoe/{boat}/*
shoe/boat?x=2
Resource Links for 70-513 WCF Certification Exam
113
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
shoe/{boat}?x={bed}
"shoe/{boat}?x={bed}&y=band"
?x={shoe}
"shoe?x=3&y={var}
Examples of invalid template strings:
{shoe}/{SHOE}/x=2 Duplicate variable names.
{shoe}/boat/?bed={shoe} Duplicate variable names.
?x=2&x=3 Name/value pairs within a query string must be unique, even if they are literals.
?x=2& Query string is malformed.
?2&x={shoe} Query string must be name/value pairs.
?y=2&&X=3 Query string must be name value pairs, names cannot start with '&'.
Compound Path Segments
Compound path segments allow a single URI path segment to contain multiple variables as well
as variables combined with literals. The following are examples of valid compound path
segments.
/filename.{ext}/
/{filename}.jpg/
/{filename}.{ext}/
/{a}.{b}someLiteral{c}({d})/
The following are examples of invalid path segments.
/{} - Variables must be named.
/{shoe}{boat} - Variables must be separated by a literal.
Matching and Compound Path Segments
Compound path segments allow you to define a UriTemplate that has multiple variables within a
single path segment. For example, in the following template string: Addresses/{state}.{city}
two variables (state and city) are defined within the same segment. This template would match a
URL such as http://example.com/Washington.Redmond but it will also match an URL like
http://example.com/Washington.Redmond.Microsoft. In the latter case, the state variable will
contain Washington and the city variable will contain Redmond.Microsoft. In this case any
text (except /) will match the {city} variable. If you want a template that will not match the
Resource Links for 70-513 WCF Certification Exam
114
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
extra text, place the variable in a separate template segment, for example:
Addresses/{state}/{city}.
Named Wildcard Segments
A named wildcard segment is any path variable segment whose variable name begins with the
wildcard character *. The following template string contains a named wildcard segment named
"shoe".
"literal/{*shoe}"
Wildcard segments must follow the following rules:
There can be at most one named wildcard segment for each template string.
A named wildcard segment must appear at the right-most segment in the path.
A named wildcard segment cannot coexist with an anonymous wildcard segment within the same
template string.
The name of a named wildcard segment must be unique.
Named wildcard segments cannot have default values.
Named wildcard segments cannot end with /.
Default Variable Values
Default variable values allow you to specify default values for variables within a template.
Default variables can be specified with the curly braces that declare the variable or as a
collection passed to the UriTemplate constructor. The following template shows two ways to
specify a UriTemplate with variables with default values.
UriTemplate t = new UriTemplate("/test/{a=1}/{b=5}");
This template declares a variable named a with a default value of 1 and a variable named b with
a default value of 5.
Note
Only path segment variables are allowed to have default values. Query string variables,
compound segment variables, and named wildcard variables are not permitted to have default
values.
The following code shows how default variable values are handled when matching a candidate
URI.
Uri baseAddress = new Uri("http://localhost:800
Dictionary<string,string> defVals = new Dictionary<string,string> {{"a","1"}, {"b", "5"}};
Resource Links for 70-513 WCF Certification Exam
115
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
UriTemplate t = new UriTemplate("/test/{a}/{b}", defVals);0");
UriTemplate t = new UriTemplate("/{state=WA}/{city=Redmond}/", true);
Uri candidate = new Uri("http://localhost:8000/OR");
UriTemplateMatch m1 = t.Match(baseAddress, candidate);
// Display contents of BoundVariables
foreach (string key in m1.BoundVariables.AllKeys)
{
Console.WriteLine("\t\t{0}={1}", key, m1.BoundVariables[key]);
}
// The output of the above code is
// Template: /{state=WA}/{city=Redmond}/
// Candidate URI: http://localhost:8000/OR
// BoundVariables:
// STATE=OR
// CITY=Redmond

Note
A URI such as http://localhost:8000/// does not match the template listed in the preceding code,
however a URI such as http://localhost:8000/ does.
The following code shows how default variable values are handled when creating a URI with a
template.
Uri baseAddress = new Uri("http://localhost:8000/");
Dictionary<string,string> defVals = new Dictionary<string,string> {{"a","1"}, {"b", "5"}};
UriTemplate t = new UriTemplate("/test/{a}/{b}", defVals);
NameValueCollection vals = new NameValueCollection();
vals.Add("a", "10");
Uri boundUri = t.BindByName(baseAddress, vals);
Console.WriteLine("BaseAddress: {0}", baseAddress);
Console.WriteLine("Template: {0}", t.ToString());
Console.WriteLine("Values: ");
foreach (string key in vals.AllKeys)
{
Console.WriteLine("\tKey = {0}, Value = {1}", key, vals[key]);
}
Console.WriteLine("Bound URI: {0}", boundUri);
Resource Links for 70-513 WCF Certification Exam
116
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
// The output of the preceding code is
// BaseAddress: http://localhost:8000/
// Template: /test/{a}/{b}
// Values:
// Key = a, Value = 10
// Bound URI: http://localhost:8000/test/10/5
When a variable is given a default value of null there are some additional constraints. A variable
can have a default value of null if the variable is contained within the right most segment of the
template string or if all segments to the right of the segment have default values of null. The
following are valid template strings with default values of null:
UriTemplate t = new UriTemplate("shoe/{boat=null}");
UriTemplate t = new UriTemplate("{shoe=null}/{boat=null}");
UriTemplate t = new UriTemplate("{shoe=1}/{boat=null}");
The following are invalid template strings with default values of null:
UriTemplate t = new UriTemplate("{shoe=null}/boat"); // null default must be in the right most path segment
UriTemplate t = new UriTemplate("{shoe=null}/{boat=x}/{bed=null}"); // shoe cannot have a null default because
boat does not have a default null value
Default Values and Matching
When matching a candidate URI with a template that has default values, the default values are
placed in the BoundVariables collection if values are not specified in the candidate URI.
Template Equivalence
Two templates are said to be structurally equivalent when all of the templates' literals match and
they have variables in the same segments. For example the following templates are structurally
equivalent:
/a/{var1}/b b/{var2}?x=1&y=2
a/{x}/b%20b/{var1}?y=2&x=1
a/{y}/B%20B/{z}/?y=2&x=1
A few things to notice:
If a template contains leading slashes, only the first one is ignored.
When comparing template strings for structural equivalence, case is ignored for variable names
and path segments, query strings are case sensitive.
Query strings are unordered.
Resource Links for 70-513 WCF Certification Exam
117
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
UriTemplateTable
The UriTemplateTable class represents an associative table of UriTemplate objects bound to an
object of the developer's choosing. A UriTemplateTable must contain at least one UriTemplate
prior to calling MakeReadOnly(Boolean). The contents of a UriTemplateTable can be changed
until MakeReadOnly(Boolean) is called. Validation is performed when
MakeReadOnly(Boolean) is called. The type of validation performed depends upon the value of
the allowMultiple parameter to MakeReadOnly(Boolean).When MakeReadOnly(Boolean) is
called passing in false, the UriTemplateTable checks to make sure there are no templates in the
table. If it finds any structurally equivalent templates, it throws an exception. This is used in
conjunction with MatchSingle(Uri) when you want to ensure only one template matches an
incoming URI.When MakeReadOnly(Boolean) is called passing in true, UriTemplateTable
allows multiple, structurally-equivalent templates to be contained within a UriTemplateTable.
If a set of UriTemplate objects added to a UriTemplateTable contain query strings they must not
be ambiguous. Identical query strings are allowed.
Note
While the UriTemplateTable allows base addresses that use schemes other than HTTP, the
scheme and port number are ignored when matching candidate URIs to templates.
Query String Ambiguity
Templates that share an equivalent path contain ambiguous query strings if there is a URI that
matches more than one template.
The following sets of query strings are unambiguous within themselves:
?x=1
?x=2
?x=3
?x=1&y={var}
?x=2&z={var}
?x=3
?x=1
?
? x={var}
Resource Links for 70-513 WCF Certification Exam
118
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
?
?m=get&c=rss
?m=put&c=rss
?m=get&c=atom
?m=put&c=atom
The following sets of query string templates are ambiguous within themselves:
?x=1
?x={var}
"x=1" - Matches both templates.
?x=1
?y=2
"x=1&y=2" matches both templates. This is because a query string may contain more query
string variables then the template it matches.
?x=1
?x=1&y={var}
"x=1&y=3" matches both templates.
?x=3&y=4
?x=3&z=5
Note
The characters and are considered to be different characters when they appear as part of a
URI path or UriTemplate path segment literal (but the characters a and A are considered to be
the same). The characters and are considered to be the same characters when they appear as
part of a UriTemplate {variableName} or a query string (and a and A are also considered to be
the same characters).
How to: Create a Service That Returns
Arbitrary Data Using The WCF Web HTTP
Programming Model
Resource Links for 70-513 WCF Certification Exam
119
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Sometimes developers must have full control of how data is returned from a service operation.
This is the case when a service operation must return data in a format not supported by WCF.
This topic discusses using the WCF WEB HTTP Programming Model to create such a service.
This service has one operation that returns a stream.
To implement the service contract
1. Define the service contract. The contract is called IImageServer and has one method called
GetImage that returns a Stream.
2. [ServiceContract]
3. public interface IImageServer
4. {
5. [WebGet]
6. Stream GetImage(int width, int height);
7. }
Because the method returns a Stream, WCF assumes that the operation has complete control over
the bytes that are returned from the service operation and it applies no formatting to the data that
is returned.
8. Implement the service contract. The contract has only one operation (GetImage). This method
generates a bitmap and then save it to a MemoryStream in .jpg format. The operation then
returns that stream to the caller.
9. public class Service : IImageServer
10. {
11. public Stream GetImage(int width, int height)
12. {
13. Bitmap bitmap = new Bitmap(width, height);
14. for (int i = 0; i < bitmap.Width; i++)
15. {
16. for (int j = 0; j < bitmap.Height; j++)
17. {
18. bitmap.SetPixel(i, j, (Math.Abs(i - j) < 2) ? Color.Blue : Color.Yellow);
19. }
20. }
21. MemoryStream ms = new MemoryStream();
22. bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
23. ms.Position = 0;
Resource Links for 70-513 WCF Certification Exam
120
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
24. WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
25. return ms;
26. }
27. }
Notice the second to last line of code:
WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
This sets the content type header to image/jpeg. Although this sample shows how to return a
.jpg file, it can be modified to return any type of data that is required, in any format. The
operation must retrieve or generate the data and then write it to a stream.
To host the service
1. Create a console application to host the service.
2. class Program
3. {
4. static void Main(string[] args)
5. {
6. }
7. }
8. Create a variable to hold the base address for the service within the Main method.
9. string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
10. Create a ServiceHost instance for the service specifying the service class and the base address.
11. ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
12.
13. Add an endpoint using the WebHttpBinding and the WebHttpBehavior.
14. host.AddServiceEndpoint(typeof(IImageServer), new WebHttpBinding(), "").Behaviors.Add(new
WebHttpBehavior());
15.
16. Open the service host.
17. host.Open()
18. Wait until the user presses ENTER to terminate the service.
19. Console.WriteLine("Service is running");
20. Console.Write("Press ENTER to close the host");
21. Console.ReadLine();
22. host.Close();
23.
Resource Links for 70-513 WCF Certification Exam
121
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
To call the raw service using Internet Explorer
1. Run the service, you should see the following output from the service. Service is running Press
ENTER to close the host
2. Open Internet Explorer and type in
http://localhost:8000/Service/GetImage?width=50&height=40 you should see a yellow rectangle
with a blue diagonal line through the center.
Example
The following is a complete listing of the code for this topic.
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.IO;
using System.Drawing;
namespace RawImageService
{
// Define the service contract
[ServiceContract]
public interface IImageServer
{
[WebGet]
Stream GetImage(int width, int height);
}
// implement the service contract
public class Service : IImageServer
{
public Stream GetImage(int width, int height)
{
// Although this method returns a jpeg, it can be
// modified to return any data you want within the stream
Bitmap bitmap = new Bitmap(width, height);
for (int i = 0; i < bitmap.Width; i++)
{
Resource Links for 70-513 WCF Certification Exam
122
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
for (int j = 0; j < bitmap.Height; j++)
{
bitmap.SetPixel(i, j, (Math.Abs(i - j) < 2) ? Color.Blue : Color.Yellow);
}
}
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Position = 0;
WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
return ms;
}
}
class Program
{
static void Main(string[] args)
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(IImageServer), new WebHttpBinding(), "").Behaviors.Add(new
WebHttpBehavior());
host.Open();
Console.WriteLine("Service is running");
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();

}
}
}
Compiling the Code
When compiling the sample code reference System.ServiceModel.dll and
System.ServiceModel.Web.dll.
Resource Links for 70-513 WCF Certification Exam
123
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
How to: Create a Service That Accepts
Arbitrary Data using the WCF REST
Programming Model
Sometimes developers must have full control of how data is returned from a service operation.
This is the case when a service operation must return data in a format not supported byWCF.
This topic discusses using the WCF REST Programming Model to create a service that receives
arbitrary data.
To implement the service contract
1. Define the service contract. The operation that receives the arbitrary data must have a parameter
of type Stream. In addition, this parameter must be the only parameter passed in the body of the
request. The operation described in this example also takes a filename parameter. This parameter
is passed within the URL of the request. You can specify that a parameter is passed within the
URL by specifying a UriTemplate in the WebInvokeAttribute. In this case the URI used to call
this method ends in UploadFile/Some-Filename. The {filename} portion of the URI
template specifies that the filename parameter for the operation is passed within the URI used to
call the operation.
2. [ServiceContract]
3. public interface IReceiveData
4. {
5. [WebInvoke(UriTemplate = "UploadFile/{fileName}")]
6. void UploadFile(string fileName, Stream fileContents);
7. }
8. Implement the service contract. The contract has only one method, UploadFile that receives a file
of arbitrary data in a stream. The operation reads the stream counting the number of bytes read
and then displays the filename and the number of bytes read.
9. public class RawDataService : IReceiveData
10. {
11. public void UploadFile(string fileName, Stream fileContents)
12. {
Resource Links for 70-513 WCF Certification Exam
124
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
13. byte[] buffer = new byte[10000];
14. int bytesRead, totalBytesRead = 0;
15. do
16. {
17. bytesRead = fileContents.Read(buffer, 0, buffer.Length);
18. totalBytesRead += bytesRead;
19. } while (bytesRead > 0);
20. Console.WriteLine("Service: Received file {0} with {1} bytes", fileName, totalBytesRead);
21. }
22. }
To host the service
1. Create a console application to host the service.
2. class Program
3. {
4. static void Main(string[] args)
5. {
6. }
7. }
8. Create a variable to hold the base address for the service within the Main method.
9. string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
10. Create a ServiceHost instance for the service that specifies the service class and the base address.
11. ServiceHost host = new ServiceHost(typeof(RawDataService), new Uri(baseAddress));
12. Add an endpoint that specifies the contract, WebHttpBinding, and WebHttpBehavior.
13. host.AddServiceEndpoint(typeof(IReceiveData), new WebHttpBinding(), "").Behaviors.Add(new
WebHttpBehavior());
14. Open the service host. The service is now ready to receive requests.
15. host.Open();
16. Console.WriteLine("Host opened");
To call the service programmatically
1. Create a HttpWebRequest with the URI used to call the service. In this code, the base address is
combined with /UploadFile/Text. The UploadFile portion of the URI specifies the operation
to call. The Test.txt portion of the URI specifies the filename parameter to pass to the
UploadFile operation. Both of these items map to the UriTemplate applied to the operation
contract.
Resource Links for 70-513 WCF Certification Exam
125
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
2. HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/UploadFile/Test.txt");
3. Set the Method property of the HttpWebRequest to POST and the ContentType property to
text/plain. This tells the service that the code is sending data and that data is in plain text.
4. req.Method = "POST";
5. req.ContentType = "text/plain";
6. Call GetRequestStream to get the request stream, create the data to send, write that data to the
request stream, and close the stream.
7. Stream reqStream = req.GetRequestStream();
8. byte[] fileToSend = new byte[12345];
9. for (int i = 0; i < fileToSend.Length; i++)
10. {
11. fileToSend[i] = (byte)('a' + (i % 26));
12. }
13. reqStream.Write(fileToSend, 0, fileToSend.Length);
14. reqStream.Close();
15. Get the response from the service by calling GetResponse and display the response data to the
console.
16. HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
17. Console.WriteLine("Client: Receive Response HTTP/{0} {1} {2}", resp.ProtocolVersion, (int)resp.StatusCode,
resp.StatusDescription);
18. Close the service host.
19. host.Close();
Example
The following is a complete listing of the code for this example.
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.IO;
using System.Net;
namespace ReceiveRawData
{
[ServiceContract]
Resource Links for 70-513 WCF Certification Exam
126
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
public interface IReceiveData
{
[WebInvoke(UriTemplate = "UploadFile/{fileName}")]
void UploadFile(string fileName, Stream fileContents);
}
public class RawDataService : IReceiveData
{
public void UploadFile(string fileName, Stream fileContents)
{
byte[] buffer = new byte[10000];
int bytesRead, totalBytesRead = 0;
do
{
bytesRead = fileContents.Read(buffer, 0, buffer.Length);
totalBytesRead += bytesRead;
} while (bytesRead > 0);
Console.WriteLine("Service: Received file {0} with {1} bytes", fileName, totalBytesRead);
}
}
class Program
{
static void Main(string[] args)
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(RawDataService), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(IReceiveData), new WebHttpBinding(), "").Behaviors.Add(new
WebHttpBehavior());
host.Open();
Console.WriteLine("Host opened");

HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(baseAddress + "/UploadFile/Test.txt");
req.Method = "POST";
req.ContentType = "text/plain";
Stream reqStream = req.GetRequestStream();
byte[] fileToSend = new byte[12345];
for (int i = 0; i < fileToSend.Length; i++)
{
Resource Links for 70-513 WCF Certification Exam
127
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
fileToSend[i] = (byte)('a' + (i % 26));
}
reqStream.Write(fileToSend, 0, fileToSend.Length);
reqStream.Close();
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Console.WriteLine("Client: Receive Response HTTP/{0} {1} {2}", resp.ProtocolVersion,
(int)resp.StatusCode, resp.StatusDescription);
host.Close();
}
}
}
Compiling the Code
When compiling the code reference System.ServiceModel.dll and System.ServiceModel.Web.dll
Caching Support for WCF Web HTTP
Services
.NET Framework 4.5 enables you to use the declarative caching mechanism already available in
ASP.NET in your WCF Web HTTP services. This allows you to cache responses from your
WCF Web HTTP service operations. When a user sends an HTTP GET to your service that is
configured for caching, ASP.NET sends back the cached response and the service method is not
called. When the cache expires, the next time a user sends an HTTP GET, your service method is
called and the response is once again cached. For more information about ASP.NET caching, see
ASP.NET Caching Overview
Basic Web HTTP Service Caching
To enable WEB HTTP service caching you must first enable ASP.NET compatibility by
applying the AspNetCompatibilityRequirementsAttribute to the service setting
RequirementsMode to Allowed or Required.
.NET Framework 4 introduces a new attribute called AspNetCacheProfileAttribute that allows
you to specify a cache profile name. This attribute is applied to a service operation. The
following example applies the AspNetCompatibilityRequirementsAttribute to a service to enable
ASP.NET compatibility and configures the GetCustomer operation for caching. The
Resource Links for 70-513 WCF Certification Exam
128
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
AspNetCacheProfileAttribute attribute specifies a cache profile that contains the cache settings
to be used.
[ServiceContract]
AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
public class Service
{
[WebGet(UriTemplate = "{id}")]
[AspNetCacheProfile("CacheFor60Seconds")]
public Customer GetCustomer(string id)
{
// ...
}
}
You must also turn on ASP.NET compatibility mode in the Web.config file as shown in the
following example.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
Caution
If ASP.NET compatibility mode is not turned on and the AspNetCacheProfileAttribute is used an
exception is thrown.
The cache profile name specified by the AspNetCacheProfileAttribute identifies a cache profile
that is added to your Web.config configuration file. The cache profile is defined with in a
<outputCacheSetting> element as shown in the following configuration example.
<!-- ... -->
<system.web>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor60Seconds" duration="60" varyByParam="none"
sqlDependency="MyTestDatabase:MyTable"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
Resource Links for 70-513 WCF Certification Exam
129
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<!-- ... -->
</system.web>
This is the same configuration element that is available to ASP.NET applications. For more
information about ASP.NET cache profiles, see OutputCacheProfile. For Web HTTP services,
the most important attributes in the cache profile are: cacheDuration and varyByParam. Both of
these attributes are required. cacheDuration sets the amount of time a response should be cached
in seconds. varyByParam allows you to specify a query string parameter that is used to cache
responses. All requests made with different query string parameter values are cached separately.
For example, once an initial request is made to
http://MyServer/MyHttpService/MyOperation?param=10 all subsequent requests made with the
same URI would be returned the cached response (so long as the cache duration has not elapsed).
Responses for a similar request that is the same but has a different value for the parameter query
string parameter are cached separately. If you do not want this separate caching behavior, set
varyByParam to "none".
SQL Cache Dependency
Web HTTP service responses can also be cached with a SQL cache dependency. If your WCF
Web HTTP service depends on data stored in a SQL database, you may want to cache the
service's response and invalidate the cached response when data in the SQL database table
changes. This behavior is configured completely within the Web.config file. You must first
define a connection string in the <connectionStrings> element.
<connectionStrings>
<add name="connectString"
connectionString="Data Source=MyService;Initial Catalog=MyTestDatabase;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
Then you must enable SQL cache dependency within a <caching> element within the
<system.web> element as shown in the following config example.
<system.web>
<caching>
<sqlCacheDependency enabled="true" pollTime="1000" >
<databases>
<add name="MyTestDatabase" connectionStringName="connectString" />
</databases>
Resource Links for 70-513 WCF Certification Exam
130
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
</sqlCacheDependency>
<!-- ... -->
</caching>
<!-- ... -->
</system.web>
Here SQL cache dependency is enabled and a polling time of 1000 milliseconds is set. Each time
the polling time elapses the database table is checked for updates. If changes are detected the
contents of the cache are removed and the next time the service operation is invoked a new
response is cached. Within the <sqlCacheDependency> element add the databases and reference
the connection strings within the <databases> element as shown in the following example.
<system.web>
<caching>
<sqlCacheDependency enabled="true" pollTime="1000" >
<databases>
<add name="MyTestDatabase" connectionStringName="connectString" />
</databases>
</sqlCacheDependency>
<!-- ... -->
</caching>
<!-- ... -->
</system.web>
Next you must configure the output cache settings within the <caching> element as shown in the
following example.
<system.web>
<caching>
<!-- ... -->
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor60Seconds" duration="60" varyByParam="none"
sqlDependency="MyTestDatabase:MyTable"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<!-- ... -->
</system.web>
Resource Links for 70-513 WCF Certification Exam
131
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Here the cache duration is set to 60 seconds, varyByParam is set to none and sqlDependency is
set to a semicolon delimited list of database name/table pairs separated by colons. When data in
MyTable is changed the cached response for the service operation is removed and when the
operation is invoked a new response is generated (by calling the service operation), cached, and
returned to the client.
Important
For ASP.NET to access a SQL database, you must use the ASP.NET SQL Server Registration
Tool. In addition you must allow the appropriate user account access to the database and table.
For more information, see Accessing SQL Server from a Web Application.
Conditional HTTP GET Based Caching
In Web HTTP scenarios a conditional HTTP GET is often used by services to implement
intelligent HTTP caching as described in the HTTP Specification. To do this the service must set
the value of the ETag header in the HTTP response. It also must check the If-None-Match header
in the HTTP request to see whether any of the ETag specified matches the current ETag.
For GET and HEAD requests, CheckConditionalRetrieve takes an ETag value and checks it
against the If-None-Match header of the request. If the header is present and there is a match, a
WebFaultException with a HTTP status code 304 (Not Modified) is thrown and an ETag header
is added to the response with the matching ETag.
One overload of the CheckConditionalRetrieve method takes a last modified date and checks it
against the If-Modified-Since header of the request. If the header is present and the resource has
not been modified since, a WebFaultException with an HTTP status code 304 (Not Modified) is
thrown.
For PUT, POST, and DELETE requests, CheckConditionalUpdate takes the current ETag value
of a resource. If the current ETag value is null, the method checks that the If-None- Match
header has a value of *. If the current ETag value is not a default value, then the method
checks the current ETag value against the If- Match header of the request. In either case, the
method throws a WebFaultException with an HTTP status code 412 (Precondition Failed) if the
expected header is not present in the request or its value does not satisfy the conditional check
and sets the ETag header of the response to the current ETag value.
Resource Links for 70-513 WCF Certification Exam
132
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Both the CheckConditional methods and the SetETag method ensures that the ETag value set on
the response header is a valid ETag according to the HTTP specification. This includes
surrounding the ETag value in double quotes if they are not already present and properly
escaping any internal double quote characters. Weak ETag comparison is not supported.
The following example shows how to use these methods.
[WebGet(UriTemplate = "{id}"), Description("Returns the specified customer from customers collection. Returns
NotFound if there is no such customer. Supports conditional GET.")]
public Customer GetCustomer(string id)
{
lock (writeLock)
{
// return NotFound if there is no item with the specified id.
object itemEtag = customerEtags[id];
if (itemEtag == null)
{
throw new WebFaultException(HttpStatusCode.NotFound);
}
// return NotModified if the client did a conditional GET and the customer item has not changed
// since when the client last retrieved it
WebOperationContext.Current.IncomingRequest.CheckConditionalRetrieve((long)itemEtag);
Customer result = this.customers[id] as Customer;
// set the customer etag before returning the result
WebOperationContext.Current.OutgoingResponse.SetETag((long)itemEtag);
return result;
}
}
Security Considerations
Requests that require authorization should not have their responses cached, because the
authorization is not performed when the response is served from the cache. Caching such
responses would introduce a serious security vulnerability. Usually, requests that require
authorization provide user-specific data and therefore server-side caching is not even beneficial.
In such situations, client-side caching or simply not caching at all will be more appropriate.
WCF Web HTTP Service Help Page
Resource Links for 70-513 WCF Certification Exam
133
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
.NET Framework 4.5 provides an automatic help page for WCF WEB HTTP services. This help
page lists a description of each operation, request and response formats, and schemas. This
functionality is turned off by default. When a user browses to a WCF WEB HTTP service and
appends "/Help" on to the end of the URL, for example http://localhost:8000/Customers/Help, a
help page like the following is displayed.

The user can then click any method listed in the help page and detailed page for that operation is
displayed showing more information about the method, including message formats and example
responses. The following image is an example of a help page for a method.
Resource Links for 70-513 WCF Certification Exam
134
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

Using the WCF Web HTTP Help Page
The WCF WEB HTTP Help page displays a short description for each operation provided that
you specify one using the DescriptionAttribute. This attribute takes a string that contains a short
description of the operation it is applied to. For example, the following code shows how to use
the DescriptionAttribute to provide a short description.
[OperationContract]
[WebGet(UriTemplate="/template1", BodyStyle = WebMessageBodyStyle.Bare)]
[Description("Description for GET /template1")]
SyndicationFeedFormatter GetTemplate1();
To turn on the WCF WEB HTTP Help page, you must add an endpoint behavior to your
service's endpoints. This can be done in configuration or code. To enable the WCF WEB HTTP
Help age in configuration, add an endpoint behavior with a <webHttp> element, set enableHelp
to true, and add an endpoint and configure it to use the endpoint behavior. The following
configuration code shows how to do this.
<endpointBehaviors>
<behavior name="RESTEndpointBehavior">
<webHttp enableHelp="true"/>
</behavior>
</endpointBehaviors>
Resource Links for 70-513 WCF Certification Exam
135
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<!-- ... -->
<services>
<service behaviorConfiguration="RESTWebServiceBehavior" name="RESTWebService"><endpoint address=""
kind="webHttpEndpoint" behaviorConfiguration="RESTEndpointBehavior" contract="IHello" />
<!-- ... -->
</service>
</services>
To enable the WCF Web HTTP Help page in code, add a service endpoint and add a
WebHttpBehavior to the endpoint setting EnableHelp to true. The following code shows how to
do this.
using (WebServiceHost host = new WebServiceHost(typeof(Service), new Uri("http://localhost:8000/Customers")))
{
host.AddServiceEndpoint(typeof(ICustomerCollection), new WebHttpBinding(), "");
host.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior { EnableHelp = true });
// ...
}
The help page is XHTML based with mark-up that identifies the different parts of the page. This
enables clients to programmatically access the page using XElement or other XLinq APIs.
Schemas Used in the WCF Web HTTP Service Help Page
The following schemas are used in the WCF Web HTTP service help page.
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified"
elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="anyType" nillable="true" type="xs:anyType" />
<xs:element name="anyURI" nillable="true" type="xs:anyURI" />
<xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
<xs:element name="boolean" nillable="true" type="xs:boolean" />
<xs:element name="byte" nillable="true" type="xs:byte" />
<xs:element name="dateTime" nillable="true" type="xs:dateTime" />
<xs:element name="decimal" nillable="true" type="xs:decimal" />
<xs:element name="double" nillable="true" type="xs:double" />
<xs:element name="float" nillable="true" type="xs:float" />
<xs:element name="int" nillable="true" type="xs:int" />
<xs:element name="long" nillable="true" type="xs:long" />
Resource Links for 70-513 WCF Certification Exam
136
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<xs:element name="QName" nillable="true" type="xs:QName" />
<xs:element name="short" nillable="true" type="xs:short" />
<xs:element name="string" nillable="true" type="xs:string" />
<xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
<xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
<xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
<xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
<xs:element name="char" nillable="true" type="tns:char" />
<xs:simpleType name="char">
<xs:restriction base="xs:int" />
</xs:simpleType>
<xs:element name="duration" nillable="true" type="tns:duration" />
<xs:simpleType name="duration">
<xs:restriction base="xs:duration">
<xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
<xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
<xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
</xs:restriction>
</xs:simpleType>
<xs:element name="guid" nillable="true" type="tns:guid" />
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
</xs:restriction>
</xs:simpleType>
<xs:attribute name="FactoryType" type="xs:QName" />
<xs:attribute name="Id" type="xs:ID" />
<xs:attribute name="Ref" type="xs:IDREF" />
</xs:schema>
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:tns="http://microsoft.com/wsdl/types/" elementFormDefault="qualified"
targetNamespace="http://microsoft.com/wsdl/types/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="guid">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
</xs:restriction>
</xs:simpleType>
Resource Links for 70-513 WCF Certification Exam
137
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<xs:simpleType name="char">
<xs:restriction base="xs:unsignedShort" />
</xs:simpleType>
</xs:schema>
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:tns="http://schemas.datacontract.org/2004/07/System" elementFormDefault="qualified"
targetNamespace="http://schemas.datacontract.org/2004/07/System"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xs:complexType name="DateTimeOffset">
<xs:annotation>
<xs:appinfo>
<IsValueType xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</IsValueType>
</xs:appinfo>
</xs:annotation>
<xs:sequence>
<xs:element name="DateTime" type="xs:dateTime" />
<xs:element name="OffsetMinutes" type="xs:short" />
</xs:sequence>
</xs:complexType>
<xs:element name="DateTimeOffset" nillable="true" type="tns:DateTimeOffset" />
<xs:complexType name="DBNull">
<xs:sequence />
</xs:complexType>
<xs:element name="DBNull" nillable="true" type="tns:DBNull" />
</xs:schema>
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
xmlns:ser="http://schemas.microsoft.com/2003/10/Serialization/" elementFormDefault="qualified"
targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
<xs:complexType name="ArrayOfboolean">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="boolean" type="xs:boolean" />
</xs:sequence>
</xs:complexType>
Resource Links for 70-513 WCF Certification Exam
138
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<xs:element name="ArrayOfboolean" nillable="true" type="tns:ArrayOfboolean" />
<xs:complexType name="ArrayOfchar">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="char" type="ser:char" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfchar" nillable="true" type="tns:ArrayOfchar" />
<xs:complexType name="ArrayOfdateTime">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="dateTime" type="xs:dateTime" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfdateTime" nillable="true" type="tns:ArrayOfdateTime" />
<xs:complexType name="ArrayOfdecimal">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="decimal" type="xs:decimal" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfdecimal" nillable="true" type="tns:ArrayOfdecimal" />
<xs:complexType name="ArrayOfdouble">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="double" type="xs:double" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfdouble" nillable="true" type="tns:ArrayOfdouble" />
<xs:complexType name="ArrayOffloat">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="float" type="xs:float" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOffloat" nillable="true" type="tns:ArrayOffloat" />
<xs:complexType name="ArrayOfguid">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="guid" type="ser:guid" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfguid" nillable="true" type="tns:ArrayOfguid" />
Resource Links for 70-513 WCF Certification Exam
139
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<xs:complexType name="ArrayOfint">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="int" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfint" nillable="true" type="tns:ArrayOfint" />
<xs:complexType name="ArrayOflong">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="long" type="xs:long" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOflong" nillable="true" type="tns:ArrayOflong" />
<xs:complexType name="ArrayOfshort">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="short" type="xs:short" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfshort" nillable="true" type="tns:ArrayOfshort" />
<xs:complexType name="ArrayOfstring">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfstring" nillable="true" type="tns:ArrayOfstring" />
<xs:complexType name="ArrayOfduration">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="duration" type="ser:duration" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfduration" nillable="true" type="tns:ArrayOfduration" />
<xs:complexType name="ArrayOfunsignedInt">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="unsignedInt" type="xs:unsignedInt" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfunsignedInt" nillable="true" type="tns:ArrayOfunsignedInt" />
<xs:complexType name="ArrayOfunsignedLong">
Resource Links for 70-513 WCF Certification Exam
140
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="unsignedLong" type="xs:unsignedLong" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfunsignedLong" nillable="true" type="tns:ArrayOfunsignedLong" />
<xs:complexType name="ArrayOfunsignedShort">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="unsignedShort" type="xs:unsignedShort" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfunsignedShort" nillable="true" type="tns:ArrayOfunsignedShort" />
<xs:complexType name="ArrayOfQName">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="QName" nillable="true" type="xs:QName" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfQName" nillable="true" type="tns:ArrayOfQName" />
</xs:schema>
For more information about the data contract serialization schema, see Data Contract Schema
Reference.
WCF Web HTTP Formatting
The WCF Web HTTP programming model allows you to dynamically determine the best format
for a service operation to return its response in. Two methods for determining an appropriate
format are supported: automatic and explicit.
Automatic Formatting
When enabled, automatic formatting chooses the best format in which to return the response. It
determines the best format by checking the following, in order:
1. The media types in the request messages Accept header.
2. The content-type of the request message.
3. The default format setting in the operation.
4. The default format setting in the WebHttpBehavior.
If the request message contains an Accept header the Windows Communication Foundation
(WCF) infrastructure searches for a type that it supports. If the Accept header specifies priorities
Resource Links for 70-513 WCF Certification Exam
141
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
for its media types, they are honored. If no suitable format is found in the Accept header, the
content-type of the request message is used. If no suitable content-type is specified, the default
format setting for the operation is used. The default format is set with the ResponseFormat
parameter of the WebGetAttribute and WebInvokeAttribute attributes. If no default format is
specified on the operation, the value of the DefaultOutgoingResponseFormat property is used.
Automatic formatting relies on the AutomaticFormatSelectionEnabled property. When this
property is set to true, the WCF infrastructure determines the best format to use. Automatic
format selection is disabled by default for backwards compatibility. Automatic format selection
can be enabled programmatically or through configuration. The following example shows how to
enable automatic format selection in code.
// This code assumes the service name is MyService and the service contract is IMyContract
Uri baseAddress = new Uri("http://localhost:8000");
WebServiceHost host = new WebServiceHost(typeof(MyService), baseAddress)
try
{
ServiceEndpoint sep = host.AddServiceEndpoint(typeof(IMyContract), new WebHttpBinding(), "");
// Check it see if the WebHttpBehavior already exists
WebHttpBehavior whb = sep.Behaviors.Find<WebHttpBehavior>();
if (whb != null)
{
whb.AutomaticFormatSelectionEnabled = true;
}
else
{
WebHttpBehavior webBehavior = new WebHttpBehavior();
webBehavior.AutomaticFormatSelectionEnabled = true;
sep.Behaviors.Add(webBehavior);
}
// Open host to start listening for messages
host.Open();
// ...
}
catch(CommunicationException ex)
{
Console.WriteLine(An exception occurred: + ex.Message());
Resource Links for 70-513 WCF Certification Exam
142
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
}


Automatic formatting can also be enabled through configuration. You can set the
AutomaticFormatSelectionEnabled property directly on the WebHttpBehavior or using the
WebHttpEndpoint. The following example shows how to enable the automatic format selection
on the WebHttpBehavior.
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp automaticFormatSelectionEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
<standardEndpoints>
<webHttpEndpoint>
<!-- the "" standard endpoint is used by WebServiceHost for auto creating a web endpoint. -->
<standardEndpoint name="" helpEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
The following example shows how to enable automatic format selection using
WebHttpEndpoint.
<system.serviceModel>
<standardEndpoints>
<webHttpEndpoint>
<!-- the "" standard endpoint is used by WebServiceHost for auto creating a web endpoint. -->
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
Explicit Formatting
As the name implies, in explicit formatting the developer determines the best format to use
within the operation code. If the best format is XML or JSON the developer sets Format to either
Resource Links for 70-513 WCF Certification Exam
143
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Xml or Json. If the Format property is not explicitly set, then the operations default format is
used.
The following example checks the format query string parameter for a format to use. If it has
been specified, it sets the operations format using Format.
public class Service : IService
{
[WebGet]
public string EchoWithGet(string s)
{
// if a format query string parameter has been specified, set the response format to that. If no such
// query string parameter exists the Accept header will be used
string formatQueryStringValue =
WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["format"];
if (!string.IsNullOrEmpty(formatQueryStringValue))
{
if (formatQueryStringValue.Equals("xml", System.StringComparison.OrdinalIgnoreCase))
{
WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Xml;
}
else if (formatQueryStringValue.Equals("json", System.StringComparison.OrdinalIgnoreCase))
{
WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Json;
}
else
{
throw new WebFaultException<string>(string.Format("Unsupported format '{0}'",
formatQueryStringValue), HttpStatusCode.BadRequest);
}
}
return "You said " + s;
}
If you need to support formats other than XML or JSON, define your operation to have a return
type of Message. Within the operation code, determine the appropriate format to use and then
create a Message object using one of the following methods:
WebOperationContext.CreateAtom10Response
Resource Links for 70-513 WCF Certification Exam
144
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
WebOperationContext.CreateJsonResponse
WebOperationContext.CreateStreamResponse
WebOperationContext.CreateTextResponse
WebOperationContext.CreateXmlResponse
Each of these methods takes content and creates a message with the appropriate format. The
WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements method can be used
to get a list of formats preferred by the client in order of decreasing preference. The following
example shows how to use
WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements to determine the
format to use and then uses the appropriate create response method to create the response
message.
public class Service : IService
{
public Message EchoListWithGet(string list)
{
List<string> returnList = new List<string>(list.Split(new char[] { ',' },
StringSplitOptions.RemoveEmptyEntries));
IList<ContentType> acceptHeaderElements =
WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements();
for (int x = 0; x < acceptHeaderElements.Count; x++)
{
string normalizedMediaType = acceptHeaderElements[x].MediaType.ToLowerInvariant();
switch (normalizedMediaType)
{
case "image/jpeg": return CreateJpegResponse(returnList);
case "application/xhtml+xml": return CreateXhtmlResponse(returnList);
case "application/atom+xml": return CreateAtom10Response(returnList);
case "application/xml": return CreateXmlResponse(returnList);
case "application/json": return CreateJsonResponse(returnList);
}
}
// Default response format is XML
return CreateXmlResponse(returnList);
}
}
Resource Links for 70-513 WCF Certification Exam
145
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

WCF Web HTTP Error Handling
Windows Communication Foundation (WCF) Web HTTP error handling enables you to return
errors from WCF Web HTTP services that specify an HTTP status code and return error details
using the same format as the operation (for example, XML or JSON).
WCF Web HTTP Error Handling
The WebFaultException class defines a constructor that allows you to specify an HTTP status
code. This status code is then returned to the client. A generic version of the WebFaultException
class, WebFaultException<T> enables you to return a user-defined type that contains
information about the error that occurred. This custom object is serialized using the format
specified by the operation and returned to the client. The following example shows how to return
an HTTP status code.
Public string Operation1()
{ // Operation logic
// ...
Throw new WebFaultException(HttpStatusCode.Forbidden);
}
The following example shows how to return an HTTP status code and extra information in a
user-defined type. MyErrorDetail is a user-defined type that contains extra information about the
error that occurred.
Public string Operation2()
// Operation logic
// ... MyErrorDetail detail = new MyErrorDetail
{
Message = Error Message,
ErrorCode = 123,
}
throw new WebFaultException<MyErrorDetail>(detail, HttpStatusCode.Forbidden);
}
The preceding code returns an HTTP response with the forbidden status code and a body that
contains an instance of the MyErrorDetails object. The format of the MyErrorDetails object is
determined by:
Resource Links for 70-513 WCF Certification Exam
146
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The value of the ResponseFormat parameter of the WebGetAttribute or WebInvokeAttribute
attribute specified on the service operation.
The value of AutomaticFormatSelectionEnabled.
The value of the Format property by accessing the OutgoingWebResponseContext.
For more information about how these values affect the formatting of the operation, see WCF
Web HTTP Formatting.
WebFaultException is a FaultException and therefore can be used as the fault exception
programming model for services that expose SOAP endpoints as well as web HTTP endpoints.
Using JSONP
JSON Padding (JSONP) is a mechanism that enables cross-site scripting support in Web
browsers. JSONP is designed around the ability of Web browsers to load scripts from a site
different from the one the current loaded document was retrieved from. The mechanism works
by padding the JSON payload with a user-defined callback function name, as shown in the
following example.
callback({"a" = \"b\" });
In the preceding example the JSON payload, {"a" = \"b\"}, is wrapped in a function call,
callback. The callback function must already be defined in the current Web page. The content
type of a JSONP response is application/javascript.
Using JSONP
JSONP is not automatically enabled. To enable it, set the javascriptCallbackEnabled attribute to
true on one of the HTTP standard endpoints (WebHttpEndpoint or WebScriptEndpoint), as
shown in the following example.
Xml
<system.serviceModel>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" javascriptCallbackEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
Resource Links for 70-513 WCF Certification Exam
147
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The name of the callback function can be specified in a query variable called callback as shown
in the following URL.
http://baseaddress/Service/RestService?callback=functionName
When invoked, the service sends a response like the following.
JScript
functionName({"root":"Something});
You can also specify the callback function name by applying the
JavascriptCallbackBehaviorAttribute to the service class, as shown in the following example.
C#
[ServiceContract]
[JavascriptCallbackBehavior(ParameterName = "$callback")]
publicclass Service1
{
[OperationContract]
[WebGet(ResponseFormat=WebMessageFormat.Json)]
publicstring GetData() { }
}
For the service shown previously, a request looks like the following.
http://baseaddress/Service/RestService?$callback=anotherFunction
When invoked, the service responds with the following.
anotherFunction ({"root":"Something});
HTTP Status Codes
JSONP responses with HTTP status codes other than 200 include a second parameter with the
numeric representation of the HTTP status code, as shown in the following example.
anotherFunction ({"root":"Something}, 201);
Validations
The following validations are performed when JSONP is enabled:
The WCF infrastructure throws an exception if javascriptCallback is enabled, a callback query-
string parameter is present in the request and the response format is set to JSON.
If the request contains the callback query string parameter but the operation is not an HTTP
GET, the callback parameter is ignored.
If the callback name is null or empty string the response is not formatted as JSONP.
Resource Links for 70-513 WCF Certification Exam
148
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Create and configure a Routing service.This objective may include but is not limited to: filters,
static and dynamic, context-based routing, content-based routing; router interfaces
Routing
The topics in this section cover the Routing Service. The Routing Service is a generic
configurable SOAP intermediary that lets you configure content-based routing, set up protocol
bridging, handle communication errors, and dynamically update routing logic at run time.
In This Section
Routing Service
Provides an overview of the features of the Routing Service.
Routing Service
Describes the features of the Routing Service.
Routing Introduction
Discusses configuration of the Routing Service.
Routing Contracts
Describes the message patterns that the Routing Service can process.
Message Filters
Discusses how message filters are used for content-based routing.
Routing Scenarios
Describes common routing scenarios.
Routing Service
The Routing Service is a generic SOAP intermediary that acts as a message router. The core
functionality of the Routing Service is the ability to route messages based on message content,
which allows a message to be forwarded to a client endpoint based on a value within the message
itself, in either the header or the message body.The RoutingService is implemented as a
Windows Communication Foundation (WCF) service in the System.ServiceModel.Routing
namespace. The Routing Service exposes one or more service endpoints that receive messages
and then routes each message to one or more client endpoints based on the message content. The
service provides the following features:
Resource Links for 70-513 WCF Certification Exam
149
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Content-based routing
o Service aggregation
o Service versioning
o Priority routing
o Dynamic configuration
Protocol bridging
SOAP processing
Advanced error handling
Backup endpoints
While it is possible to create an intermediary service that accomplishes one or more of these
goals, often such an implementation is tied to a specific scenario or solution and cannot be
readily applied to new applications.The Routing Service provides a generic, dynamically
configurable, pluggable SOAP intermediary that is compatible with the WCF Service and
Channel models and allows you to perform content-based routing of SOAP-based messages.
Note:
The Routing Service does not currently support routing of WCF REST services. To route REST calls,
consider using System.Web.Routing or Application Request Routing
(http://go.microsoft.com/fwlink/?LinkId=164589).
Content-Based Routing
Content-based routing is the ability to route a message based on one or more values contained
within the message. The Routing Service inspects each message and routes it to the destination
endpoint based on the message contents and the routing logic you create. Content-based routing
provides the basis for service aggregation, service versioning, and priority routing.
To implement content-based routing, the Routing Service relies on MessageFilter
implementations that are used to match specific values within the messages to be routed. If a
MessageFilter matches a message, the message is routed to the destination endpoint associated
with the MessageFilter. Message filters are grouped together into filter tables
(FilterTableCollection) to construct complex routing logic. For example, a filter table might
contain five mutually exclusive message filters that cause messages to be routed to only one of
the five destination endpoints.The Routing Service allows you to configure the logic that is used
to perform content-based routing, as well as dynamically update the routing logic at run time.
Resource Links for 70-513 WCF Certification Exam
150
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Through the grouping of message filters into filter tables, routing logic can be constructed that
allows you to handle multiple routing scenarios such as:
Service aggregation
Service versioning
Priority routing
Dynamic configuration
For more information about message filters and filter tables, see Routing Introduction and
Message Filters.
Service Aggregation
By using content-based routing, you can expose one endpoint that receives messages from
external client applications and then routes each message to the appropriate internal endpoint
based on a value within the message. This is useful to offer one specific endpoint for a variety of
back-end applications, and also to present one application endpoint to customers while factoring
your application into a variety of services.
Service Versioning
When migrating to a new version of your solution, you may have to maintain the old version in
parallel to serve existing customers. Often this requires that clients connecting to the newer
version must use a different address when communicating with the solution. The Routing Service
allows you to expose one service endpoint that serves both versions of your solution by routing
messages to the appropriate solution based on version-specific information contained in the
message. For an example of such an implementation see How To: Service Versioning.
Priority Routing
When providing a service for multiple clients, you may have a service level agreement (SLA)
with some partners that requires all data from these partners to be processed separately from that
of other clients. By using a filter that looks for customer-specific information contained in the
message, you can easily route messages from specific partners to an endpoint that has been
created to meet their SLA requirements.
Dynamic Configuration
To support mission-critical systems, where messages must be processed without any service
interruptions, it is vital that you be able to modify the configuration of components within the
Resource Links for 70-513 WCF Certification Exam
151
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
system at run time. To support this need, the Routing Service provides an IExtension
implementation, the RoutingExtension, which allows dynamic updating of the Routing Service
configuration at run time.For more information about dynamic configuration of the Routing
Service, see Routing Introduction.
Protocol Bridging
One of the challenges in intermediary scenarios is that the internal endpoints may have different
transport or SOAP version requirements than the endpoint that messages are received on. To
support this scenario, the Routing Service can bridge protocols, including processing the SOAP
message to the MessageVersion required by the destination endpoint(s). In this way, one
protocol can be used for internal communication, while another can be used for external
communication.To support the routing of messages between endpoints with different transports,
the Routing Service uses system-provided bindings that enable the service to bridge dissimilar
protocols. This occurs automatically when the service endpoint exposed by the Routing Service
uses a different protocol than the client endpoints that messages are routed to.
SOAP Processing
A common routing requirement is the ability to route messages between endpoints with differing
SOAP requirements. To support this requirement, the Routing Service provides a
SoapProcessingBehavior that automatically creates a new MessageVersion that meets the
requirements of the destination endpoint before the message is routed to it. This behavior also
creates a new MessageVersion for any response message before returning it to the requesting
client application, to ensure that the MessageVersion of the response matches that of the original
request.For more information about SOAP processing, see Routing Introduction.
Error Handling
In a system composed of distributed services that rely on network communications, it is
important to ensure that communications within your system are resistant to transient network
failures. The Routing Service implements error handling that allows you to handle many
communication failure scenarios that might otherwise result in a service outage.If the Routing
Service encounters a CommunicationException while attempting to send a message, error
handling will take place. These exceptions typically indicate that a problem was encountered
Resource Links for 70-513 WCF Certification Exam
152
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
while attempting to communicate with the defined client endpoint, such as an
EndpointNotFoundException, ServerTooBusyException, or
CommunicationObjectFaultedException. The error-handling code will also catch and attempt to
retry sending when a TimeoutException occurs, which is another common exception that is not
derived from CommunicationException.For more information about error handling, see
Routing Introduction.
Backup Endpoints
In addition to the destination client endpoints associated with each filter definition in the filter
table, you can also create a list of backup endpoints that the message will be routed to in the
event of a transmission failure. If an error occurs and a backup list is defined for the filter entry,
the Routing Service will attempt to send the message to the first endpoint defined in the list. If
this transmission attempt fails, the service will try the next endpoint, and continue this process
until the transmission attempt succeeds, returns a non-transmission related error, or all endpoints
in the backup list have returned a transmission error.For more information about backup
endpoints, see Routing Introduction and Message Filters.
Streaming
The routing service can successfully stream messages if you set the binding to support streaming.
However, there are some conditions under which messages may need to buffered:
Multicast (buffer to create additional message copies)
Failover (buffer in case the message needs to be sent to a backup)
System.ServiceModel.Routing.RoutingConfiguration.RouteOnHeadersOnly is false (buffer to present the
MessageFilterTable with a MessageBuffer so that filters can inspect the body)
Dynamic configuration
Routing Service
1 out of 1 rated this helpful - Rate this topic
The Routing Service is a generic SOAP intermediary that acts as a message router. The core
functionality of the Routing Service is the ability to route messages based on the message
content, which allows a message to be forwarded to a client endpoint based on a value within the
message itself, in either the header or the message body.The RoutingService is implemented as a
Resource Links for 70-513 WCF Certification Exam
153
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
WCF service in the System.ServiceModel.Routing namespace. The Routing Service exposes one
or more service endpoints that receive messages and then routes each message to one or more
client endpoints based on the message content. The service provides the following features:
Content-based routing
o Dynamic configuration
Protocol bridging
SOAP processing
Advanced error handling
Content-Based Routing
To implement content-based routing, the Routing Service relies on MessageFilter
implementations that are used to match specific values within the messages to be routed. If a
MessageFilter matches a message, the message is routed to the destination endpoint associated
with the MessageFilter. Message filters are grouped together into filter tables
(FilterTableCollection) to construct complex routing logic. For example, a filter table might
contain five mutually exclusive message filters that cause messages to be routed to only one of
the five destination endpoints.Through the grouping of message filters into filter tables, routing
logic can be constructed that allows you to handle multiple routing scenarios such as:
Service aggregation
Service versioning
Priority routing
For more information about message filters and filter tables, see Routing Introduction and
Message Filters.
Dynamic Configuration
To support mission-critical systems, where messages must be processed without any service
interruptions, it is vital that you be able to modify the configuration of components within the
system at run time. To support this need, the Routing Service provides an IExtension
implementation, the RoutingExtension, which allows dynamic updating of the Routing Service
configuration at run time.For more information about dynamic configuration of the Routing
Service, see Routing Introduction.
Protocol Bridging
Resource Links for 70-513 WCF Certification Exam
154
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
To support the routing of messages between endpoints with different transports, the Routing
Service uses system-provided bindings that enable the service to bridge dissimilar protocols.
This occurs automatically when the service endpoint exposed by the Routing Service uses a
different protocol than the client endpoints that messages are routed to.
SOAP Processing
A common routing requirement is the ability to route messages between endpoints with differing
SOAP requirements. To support this requirement, the Routing Service provides a
SoapProcessingBehavior that automatically creates a new MessageVersion that meets the
requirements of the destination endpoint before the message is routed to it. This behavior also
creates a new MessageVersion for any response message before returning it to the requesting
client application, to ensure that the MessageVersion of the response matches that of the original
request.For more information about SOAP processing, see Routing Introduction.
Error Handling
In a system composed of distributed services that rely on network communications, it is
important to ensure that communications within your system are resistant to transient network
failures. The Routing Service implements error handling that allows you to handle many
communication failure scenarios that might otherwise result in a service outage.
If the Routing Service encounters a CommunicationException while attempting to send a
message, error handling will take place. These exceptions typically indicate that a problem was
encountered while attempting to communicate with the defined client endpoint, such as an
EndpointNotFoundException, ServerTooBusyException, or
CommunicationObjectFaultedException. The error-handling code will also catch and attempt to
retry sending when a TimeoutException occurs, which is another common exception that is not
derived from CommunicationException.For more information about error handling, see
Routing Introduction.
Backup Endpoints
In addition to the destination client endpoints associated with each filter definition in the filter
table, you can also create a list of backup endpoints that the message will be routed to in the
event of a transmission failure. If an error occurs and a backup list is defined for the filter entry,
Resource Links for 70-513 WCF Certification Exam
155
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
the Routing Service will attempt to send the message to the first endpoint defined in the list. If
this transmission attempt fails, the service will try the next endpoint, and continue this process
until the transmission attempt succeeds, returns a non-transmission related error, or all endpoints
in the backup list have returned a transmission error.For more information about backup
endpoints, see Routing Introduction and Message Filters.
Routing Introduction
The Routing Service provides a generic pluggable SOAP intermediary that is capable of routing
messages based on message content. With the Routing Service, you can create complex routing
logic that allows you to implement scenarios such as service aggregation, service versioning,
priority routing, and multicast routing. The Routing Service also provides error handling that
allows you to set up lists of backup endpoints, to which messages are sent if a failure occurs
when sending to the primary destination endpoint. This topic is intended for those new to the
Routing Service and covers basic configuration and hosting of the Routing Service.
Configuration
The Routing Service is implemented as a WCF service that exposes one or more service
endpoints that receive messages from client applications and route the messages to one or more
destination endpoints. The service provides a RoutingBehavior, which is applied to the service
endpoints exposed by the service. This behavior is used to configure various aspects of how the
service operates. For ease of configuration when using a configuration file, the parameters are
specified on the RoutingBehavior. In code-based scenarios, these parameters would be specified
as part of a RoutingConfiguration object, which can then be passed to a RoutingBehavior.
When starting, this behavior adds the SoapProcessingBehavior, which is used to perform SOAP
processing of messages, to the client endpoints. This allows the Routing Service to transmit
messages to endpoints that require a different MessageVersion than the endpoint the message
was received over. The RoutingBehavior also registers a service extension, the
RoutingExtension, which provides an accessibility point for modifying the Routing Service
configuration at run time.The RoutingConfiguration class provides a consistent means of
configuring and updating the configuration of the Routing Service. It contains parameters that act
Resource Links for 70-513 WCF Certification Exam
156
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
as the settings for the Routing Service and is used to configure the RoutingBehavior when the
service starts, or is passed to the RoutingExtension to modify routing configuration at run time.
The routing logic used to perform content-based routing of messages is defined by grouping
multiple MessageFilter objects together into filter tables (MessageFilterTable objects). Incoming
messages are evaluated against the message filters contained in the filter table, and for each
MessageFilter that matches the message, forwarded to a destination endpoint. The filter table
that should be used to route messages is specified by using either the RoutingBehavior in
configuration or through code by using the RoutingConfiguration object.
Defining Endpoints
While it may seem that you should start your configuration by defining the routing logic you will
use, your first step should actually be to determine the shape of the endpoints you will be routing
messages to. The Routing Service uses contracts that define the shape of the channels used to
receive and send messages, and therefore the shape of the input channel must match that of the
output channel. For example, if you are routing to endpoints that use the request-reply channel
shape, then you must use a compatible contract on the inbound endpoints, such as the
IRequestReplyRouter.This means that if your destination endpoints use contracts with multiple
communication patterns (such as mixing one-way and two-way operations,) you cannot create a
single service endpoint that can receive and route messages to all of them. You must determine
which endpoints have compatible shapes and define one or more service endpoints that will be
used to receive messages to be routed to the destination endpoints.
Note:
When working with contracts that specify multiple communication patterns (such as a mix of one-way
and two-way operations,) a workaround is to use a duplex contract at the Routing Service such as
IDuplexSessionRouter. However this means that the binding must be capable of duplex communication,
which may not be possible for all scenarios. In scenarios where this is not possible, factoring the
communication into multiple endpoints or modifying the application may be necessary.
For more information about routing contracts, see Routing Contracts.
After the service endpoint is defined, you can use the RoutingBehavior to associate a specific
RoutingConfiguration with the endpoint. When configuring the Routing Service by using a
configuration file, the RoutingBehavior is used to specify the filter table that contains the
routing logic used to process messages received on this endpoint. If you are configuring the
Resource Links for 70-513 WCF Certification Exam
157
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Routing Service programmatically you can specify the filter table by using the
RoutingConfiguration.
The following example defines the service and client endpoints that are used by the Routing
Service both programmatically and by using a configuration file.
XML
<services>
<!--ROUTING SERVICE -->
<servicebehaviorConfiguration="routingData"
name="System.ServiceModel.Routing.RoutingService">
<host>
<baseAddresses>
<addbaseAddress="http://localhost:8000/routingservice/router"/>
</baseAddresses>
</host>
<!-- Define the service endpoints that are receive messages -->
<endpoint address="" binding="wsHttpBinding" name="reqReplyEndpoint"
contract="System.ServiceModel.Routing.IRequestReplyRouter" /></service>
</services>
<behaviors>
<serviceBehaviors>
<behaviorname="routingData">
<serviceMetadatahttpGetEnabled="True"/>
<!-- Add the RoutingBehavior and specify the Routing Table to use -->
<routingfilterTableName="routingTable1" />
</behavior>
</serviceBehaviors>
</behaviors>
<client>
<!-- Define the client endpoint(s) to route messages to -->
<endpointname="CalculatorService"
address="http://localhost:8000/servicemodelsamples/service"
binding="wsHttpBinding" contract="*" />
</client>
C#
//set up some communication defaults
string clientAddress = "http://localhost:8000/servicemodelsamples/service";
Resource Links for 70-513 WCF Certification Exam
158
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
string routerAddress = "http://localhost:8000/routingservice/router";
Binding routerBinding = new WSHttpBinding();
Binding clientBinding = new WSHttpBinding();
//add the endpoint the router uses to receive messages
serviceHost.AddServiceEndpoint(
typeof(IRequestReplyRouter),
routerBinding,
routerAddress);
//create the client endpoint the router routes messages to
ContractDescription contract = ContractDescription.GetContract(
typeof(IRequestReplyRouter));
ServiceEndpoint client = new ServiceEndpoint(
contract,
clientBinding,
new EndpointAddress(clientAddress));
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
.
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
//attach the behavior to the service host
serviceHost.Description.Behaviors.Add(
new RoutingBehavior(rc));
This example configures the Routing Service to expose a single endpoint with an address of
http://localhost:8000/routingservice/router, which is used to receive messages to be routed.
Because the messages are routed to request-reply endpoints, the service endpoint uses the
IRequestReplyRouter contract. This configuration also defines a single client endpoint of
http://localhost:8000/servicemodelsample/service that messages are routed to. The filter table
(not shown) named routingTable1 contains the routing logic used to route messages, and is
associated with the service endpoint by using the RoutingBehavior (for a configuration file) or
RoutingConfiguration (for programmatic configuration).
Routing Logic
To define the routing logic used to route messages, you must determine what data contained
within the incoming messages can be uniquely acted upon. For example, if all the destination
endpoints you are routing to share the same SOAP Actions, the value of the Action contained
Resource Links for 70-513 WCF Certification Exam
159
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
within the message is not a good indicator of which specific endpoint the message should be
routed to. If you must uniquely route messages to one specific endpoint, you should filter upon
data that uniquely identifies the destination endpoint that the message is routed to.
The Routing Service provides several MessageFilter implementations that inspect specific
values within the message, such as the address, action, endpoint name, or even an XPath query.
If none of these implementations meet your needs you can create a custom MessageFilter
implementation. For more information about message filters and a comparison of the
implementations used by the Routing Service, see Message Filters and Choosing a Filter.
Multiple message filters are organized together into filter tables, which associate each
MessageFilter with a destination endpoint. Optionally, the filter table can also be used to specify
a list of back-up endpoints that the Routing Service will attempt to send the message to in the
event of a transmission failure.By default all message filters within a filter table are evaluated
simultaneously; however, you can specify a Priority that causes the message filters to be
evaluated in a specific order. All entries with the highest priority are evaluated first, and message
filters of lower priorities are not evaluated if a match is found at a higher priority level. For more
information about filter tables, see Message Filters.
The following examples use the MatchAllMessageFilter, which evaluates to true for all
messages. This MessageFilter is added to the routingTable1 filter table, which associates the
MessageFilter with the client endpoint named CalculatorService. The RoutingBehavior then
specifies that this table should be used to route messages processed by the service endpoint.
XML
<behaviors>
<serviceBehaviors>
<behaviorname="routingData">
<serviceMetadatahttpGetEnabled="True"/>
<!-- Add the RoutingBehavior and specify the Routing Table to use -->
<routingfilterTableName="routingTable1" />
</behavior>
</serviceBehaviors>
</behaviors>
<!--ROUTING SECTION -->
<routing>
<filters>
Resource Links for 70-513 WCF Certification Exam
160
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<filtername="MatchAllFilter1" filterType="MatchAll" />
</filters>
<filterTables>
<tablename="routingTable1">
<filters>
<addfilterName="MatchAllFilter1" endpointName="CalculatorService" />
</filters>
</table>
</filterTables>
</routing>
C#
//create a new routing configuration object
RoutingConfiguration rc = new RoutingConfiguration();
//create the endpoint list that contains the endpoints to route to
//in this case we have only one
List<ServiceEndpoint> endpointList = new List<ServiceEndpoint>();
endpointList.Add(client);
//add a MatchAll filter to the Router's filter table
//map it to the endpoint list defined earlier
//when a message matches this filter, it is sent to the endpoint contained in the list
rc.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
Note:
By default, the Routing Service only evaluates the headers of the message. To allow the filters to access
the message body, you must set RouteOnHeadersOnly to false.
Multicast
While many Routing Service configurations use exclusive filter logic that routes messages to
only one specific endpoint, you may need to route a given message to multiple destination
endpoints. To multicast a message to multiple destinations, the following conditions must be
true:
The channel shape must not be request-reply (though may be one-way or duplex,) because only one reply
can be received by the client application in response to the request.
Multiple filters must return true when evaluating the message.
If these conditions are met, the message is routed to all endpoints of all filters that evaluate to
true. The following example defines a routing configuration that results in messages being
Resource Links for 70-513 WCF Certification Exam
161
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
routed to both endpoints if the endpoint address in the message is
http://localhost:8000/routingservice/router/rounding.
XML
<!--ROUTING SECTION -->
<routing>
<filters>
<filtername="MatchAllFilter1" filterType="MatchAll" />
<filtername="RoundingFilter1" filterType="EndpointAddress"
filterData="http://localhost:8000/routingservice/router/rounding" />
</filters>
<filterTables>
<tablename="routingTable1">
<filters>
<addfilterName="MatchAllFilter1" endpointName="CalculatorService" />
<addfilterName="RoundingFilter1" endpointName="RoundingCalcService" />
</filters>
</table>
</filterTables>
</routing>
C#
rc.FilterTable.Add(new MatchAllMessageFilter(), calculatorEndpointList);
rc.FilterTable.Add(new EndpointAddressMessageFilter(new EndpointAddress(
"http://localhost:8000/routingservice/router/rounding")), roundingCalcEndpointList);
SOAP Processing
To support the routing of messages between dissimilar protocols, the RoutingBehavior by
default adds the SoapProcessingBehavior to all client endpoint(s) that messages are routed to.
This behavior automatically creates a new MessageVersion before routing the message to the
endpoint, as well as creating a compatible MessageVersion for any response document before
returning it to the requesting client application.The steps taken to create a new MessageVersion
for the outbound message are as follows:
Request processing
Get the MessageVersion of the outbound binding/channel.
Get the body reader for the original message.
Create a new message with the same action, body reader, and a new MessageVersion.
Resource Links for 70-513 WCF Certification Exam
162
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
If Addressing != Addressing.None, copy the To, From, FaultTo, and RelatesTo headers to the new
message.
Copy all message properties to the new message.
Store the original request message to use when processing the response.
Return the new request message.
Response processing
Get the MessageVersion of the original request message.
Get the body reader for the received response message.
Create a new response message with the same action, body reader, and the MessageVersion of the
original request message.
If Addressing != Addressing.None, copy the To, From, FaultTo, and RelatesTo headers to the new
message.
Copy the message properties to the new message.
Return the new response message.
By default, the SoapProcessingBehavior is automatically added to the client endpoints by the
RoutingBehavior when the service starts; however, you can control whether SOAP processing
is added to all client endpoints by using the SoapProcessingEnabled property. You can also add
the behavior directly to a specific endpoint and enable or disable this behavior at the endpoint
level if a more granular control of SOAP processing is required.
Note:
If SOAP processing is disabled for an endpoint that requires a different MessageVersion than that of the
original request message, you must provide a custom mechanism for performing any SOAP modifications
that are required before sending the message to the destination endpoint.
In the following examples, the soapProcessingEnabled property is used to prevent the
SoapProcessingBehavior from being automatically added to all client endpoints.
XML
<behaviors>
<!--default routing service behavior definition-->
<serviceBehaviors>
<behaviorname="routingConfiguration">
<routingfilterTableName="filterTable1" soapProcessingEnabled="false"/>
</behavior>
</serviceBehaviors>
Resource Links for 70-513 WCF Certification Exam
163
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
</behaviors>
C#
//create the default RoutingConfiguration
RoutingConfiguration rc = new RoutingConfiguration();
rc.SoapProcessingEnabled = false;
Dynamic Configuration
When you add additional client endpoints, or need to modify the filters that are used to route
messages, you must have a way to update the configuration dynamically at run time to prevent
interrupting the service to the endpoints currently receiving messages through the Routing
Service. Modifying a configuration file or the code of the host application is not always
sufficient, because either method requires recycling the application, which would lead to the
potential loss of any messages currently in transit and the potential for downtime while waiting
on the service to restart.You can only modify the RoutingConfiguration programmatically.
While you can initially configure the service by using a configuration file, you can only modify
the configuration at run time by constructing a new RoutingConfigution and passing it as a
parameter to the ApplyConfiguration method exposed by the RoutingExtension service
extension. Any messages currently in transit continue to be routed using the previous
configuration, while messages received after the call to ApplyConfiguration use the new
configuration. The following example demonstrates creating an instance of the Routing Service
and then subsequently modifying the configuration.
C#
RoutingConfiguration routingConfig = new RoutingConfiguration();
routingConfig.RouteOnHeadersOnly = true;
routingConfig.FilterTable.Add(new MatchAllMessageFilter(), endpointList);
RoutingBehavior routing = new RoutingBehavior(routingConfig);
routerHost.Description.Behaviors.Add(routing);
routerHost.Open();
// Construct a new RoutingConfiguration
RoutingConfiguration rc2 = new RoutingConfiguration();
ServiceEndpoint clientEndpoint = new ServiceEndpoint();
ServiceEndpoint clientEndpoint2 = new ServiceEndpoint();
// Add filters to the FilterTable in the new configuration
rc2.FilterTable.add(new MatchAllMessageFilter(),
Resource Links for 70-513 WCF Certification Exam
164
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
new List<ServiceEndpoint>() { clientEndpoint });
rc2.FilterTable.add(new MatchAllMessageFilter(),
new List<ServiceEndpoint>() { clientEndpoint2 });
rc2.RouteOnHeadersOnly = false;
// Apply the new configuration to the Routing Service hosted in
routerHost.routerHost.Extensions.Find<RoutingExtension>().ApplyConfiguration(rc2);
Note:
When updating the Routing Service in this manner it is only possible to pass a new configuration. It is not
possible to modify only select elements of the current configuration or append new entries to the current
configuration; you must create and pass a new configuration that replaces the existing one.
Note:
Any sessions opened using the previous configuration continue using the previous configuration. The new
configuration is only used by new sessions.
Error Handling
If any CommunicationException is encountered while attempting to send a message, error
handling take place. These exceptions typically indicate that a problem was encountered while
attempting to communicate with the defined client endpoint, such as an
EndpointNotFoundException, ServerTooBusyException, or
CommunicationObjectFaultedException. The error handling-code will also catch and attempt to
retry sending when a TimeoutException occurs, which is another common exception that is not
derived from CommunicationException.When one of the preceding exceptions occurs, the
Routing Service fails over to a list of backup endpoints. If all backup endpoints fail with a
communications failure, or if an endpoint returns an exception that indicates a failure within the
destination service, the Routing Service returns a fault to the client application.
Note:
The error-handling functionality captures and handles exceptions that occur when attempting to send a message
and when attempting to close a channel. The error-handling code is not intended to detect or handle exceptions
created by the application endpoints it is communicating with; a FaultException thrown by a service appears at
the Routing Service as a FaultMessage and is flowed back to the client.
If an error occurs when the routing service tries to relay a message, you may get a FaultException on the client
side, rather than a EndpointNotFoundException you would normally get in the absence of the routing service. A
Resource Links for 70-513 WCF Certification Exam
165
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
routing service may thus mask exceptions and not provide full transparency unless you examine nested
exceptions.
Tracing Exceptions
When sending a message to an endpoint in a list fails, the Routing Service traces the resulting
exception data and attaches the exception details as a message property named Exceptions. This
preserves the exception data and allows a user programmatic access through a message inspector.
The exception data is stored per message in a dictionary that maps the endpoint name to the
exception details encountered when trying to send a message to it.
Backup Endpoints
Each filter entry within the filter table can optionally specify a list of backup endpoints, which
are used in the event of a transmission failure when sending to the primary endpoint. If such a
failure occurs, the Routing Service attempts to transmit the message to the first entry in the
backup endpoint list. If this send attempt also encounters a transmission failure, the next
endpoint in the backup list is tried. The Routing Service continues sending the message to each
endpoint in the list until the message is successfully received, all endpoints return a transmission
failure, or a non-transmission failure is returned by an endpoint.
The following examples configure the Routing Service to use a backup list.
XML
<routing>
<filters>
<!-- Create a MatchAll filter that catches all messages -->
<filtername="MatchAllFilter1" filterType="MatchAll" />
</filters>
<filterTables>
<!-- Set up the Routing Service's Message Filter Table -->
<filterTablename="filterTable1">
<!-- Add an entry that maps the MatchAllMessageFilter to the dead destination -->
<!-- If that endpoint is down, tell the Routing Service to try the endpoints -->
<!-- Listed in the backupEndpointList -->
<addfilterName="MatchAllFilter1" endpointName="deadDestination" backupList="backupEndpointList"/>
</filterTable>
</filterTables>
<!-- Create the backup endpoint list -->
Resource Links for 70-513 WCF Certification Exam
166
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<backupLists>
<!-- Add an endpoint list that contains the backup destinations -->
<backupListname="backupEndpointList">
<addendpointName="realDestination" />
<addendpointName="backupDestination" />
</backupList>
</backupLists>
</routing>
C#
//create the endpoint list that contains the service endpoints we want to route to
List<ServiceEndpoint> backupList = new List<ServiceEndpoint>();
//add the endpoints in the order that the Routing Service should contact them
//first add the endpoint that we know is down
//clearly, normally you wouldn't know that this endpoint was down by default
backupList.Add(fakeDestination);
//then add the real Destination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationException when sending
//to the previous endpoint in the list.
backupList.Add(realDestination);
//add the backupDestination endpoint
//the Routing Service attempts to send to this endpoint only if it
//encounters a TimeOutException or CommunicationsException when sending
//to the previous endpoints in the list
backupList.Add(backupDestination);
//create the default RoutingConfiguration option
RoutingConfiguration rc = new RoutingConfiguration();
//add a MatchAll filter to the Routing Configuration's filter table
//map it to the list of endpoints defined above
//when a message matches this filter, it is sent to the endpoints in the list in order
//if an endpoint is down or doesn't respond (which the first endpoint won't
//since the client doesn't exist), the Routing Service automatically moves the message
//to the next endpoint in the list and try again.
rc.FilterTable.Add(new MatchAllMessageFilter(), backupList);
Supported Error Patterns
Resource Links for 70-513 WCF Certification Exam
167
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The following table describes the patterns that are compatible with the use of backup endpoint
lists, along with notes describing the details of error handling for specific patterns.
Pattern Session
Tran
sactio
n
Recei
ve
Cont
ext
Back
up
List
Supp
orted
Notes
One-
Way
Yes
Attempts to resend the message on a backup endpoint. If this
message is being multicast, only the message on the failed
channel is moved to its backup destination.
One-
Way


No An exception is thrown and the transaction is rolled back.
One-
Way

Yes
Attempts to resend the message on a backup endpoint. After
the message is successfully received, complete all receive
contexts. If the message is not successfully received by any
endpoint, do not complete the receive context.
When this message is being multicast, the receive context is
only completed if the message is successfully received by at
least one endpoint (primary or backup). If none of the
endpoints in any of the multicast paths successfully receive
the message, do not complete the receive context.
One-
Way

Yes
Abort the previous transaction, create a new transaction, and
resend all messages. Messages that encountered an error are
transmitted to a backup destination.
After a transaction has been created in which all
transmissions succeed, complete the receive contexts and
commit the transaction.
One-
Way


Yes
Attempts to resend the message on a backup endpoint. In a
multicast scenario only the messages in a session that
Resource Links for 70-513 WCF Certification Exam
168
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
encountered an error or in a session whose session close
failed are resent to backup destinations.
One-
Way


No An exception is thrown and the transaction is rolled back.
One-
Way



Yes
Attempts to resend the message on a backup endpoint. After
all message sends complete without error, the session
indicates no more messages and the Routing Service
successfully closes all outbound session channel(s), all
receive contexts are completed, and the inbound session
channel is closed.
One-
Way

Yes
Abort the current transaction and create a new one. Resend
all previous messages in the session. After a transaction has
been created in which all messages have been successfully
sent and the session indicates no more messages, all the
outbound session channels are closed, receive contexts are
all completed with the transaction, the inbound session
channel is closed, and the transaction is committed.
When the sessions are being multicast the messages that had
no error are resent to the same destination as before, and
messages that encountered an error are sent to backup
destinations.
Two-
Way
Yes
Send to a backup destination. After a channel returns a
response message, return the response to the original client.
Two-
Way


Yes
Send all messages on the channel to a backup destination.
After a channel returns a response message, return the
response to the original client.
Two-
Way


No An exception is thrown and the transaction is rolled back.
Two-


No An exception is thrown and the transaction is rolled back.
Resource Links for 70-513 WCF Certification Exam
169
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Way
Duplex

No
Non-session duplex communication is not currently
supported.
Duplex


Yes Send to a backup destination.
Hosting
Because the Routing Service is implemented as a WCF service, it must be either self-hosted
within an application or hosted by IIS or WAS. It is recommended that the Routing Service be
hosted in either IIS, WAS, or a Windows Service application to take advantage of the automatic
start and life-cycle management features available in these hosting environments.
The following example demonstrates hosting the Routing Service in an application.
C#
using (ServiceHost serviceHost = new ServiceHost(typeof(RoutingService)))
To host the Routing Service within IIS or WAS, you must either create a service file (.svc) or use
configuration-based activation of the service. When using a service file, you must specify the
RoutingService using the Service parameter. The following example contains a sample service
file that can be used to host the Routing Service with IIS or WAS.
<%@ ServiceHost Language="C#" Debug="true" Service="System.ServiceModel.Routing.RoutingService,
System.ServiceModel.Routing, version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
Routing Contracts
Routing contracts define the message patterns that the Routing Service can process. Each
contract is typeless and allows the service to receive a message without knowledge of the
message schema or action. This allows the Routing Service to generically route messages
without additional configuration for the specifics of the underlying messages being routed.
Routing Contracts
Because the Routing Service accepts a generic WCF Message object, the most important
consideration when selecting a contract is the shape of the channel that will be used when
communicating with the clients and services. When processing messages, the Routing Service
uses symmetrical message pumps, so generally the shape of the inbound contract must match the
shape of the outbound contract. However, there are cases where the Service Models dispatcher
Resource Links for 70-513 WCF Certification Exam
170
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
can modify the shapes, such as when the dispatcher converts a duplex channel into a request-
reply channel, or removes the session support from a channel when it is not required and is not
being used (that is, when SessionMode.Allowed, converting an IInputSessionChannel into an
IInputChannel).To support these message pumps, the Routing Service provides contracts in the
System.ServiceModel.Routing namespace, which must be used when defining the service
endpoints used by the Routing Service. These contracts are typeless, which allows the receipt of
any message type or action, and allows the Routing Service to handle messages without
knowledge of the specific message schema. For more information about the contracts used by the
Routing Service, see Routing Contracts.The contracts provided by the Routing Service are
located in the System.ServiceModel.Routing namespace, and are described in the following
table.
Contract Shape Channel Shape
ISimplexDatagramRout
er
SessionMode = SessionMode.Allowed
AsyncPattern = true
IsOneWay = true
IInputChannel ->
IOutputChannel
ISimplexSessionRouter
SessionMode = SessionMode.Required
AsyncPattern = true
IsOneWay = true
IInputSessionChannel ->
IOutputSessionChannel
IRequestReplyRouter
SessionMode = SessionMode.Allowed
AsyncPattern = true
IReplyChannel ->
IRequestChannel
IDuplexSessionRouter
SessionMode=SessionMode.Required
CallbackContract=typeof(ISimplexSession)
AsyncPattern = true
IsOneWay = true
TransactionFlow(TransactionFlowOption.
Allowed)
IDuplexSessionChannel ->
IDuplexSessionChannel
Message Filters
To implement content-based routing, the Routing Service uses MessageFilter implementations
that inspect specific sections of a message, such as the address, endpoint name, or a specific
Resource Links for 70-513 WCF Certification Exam
171
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
XPath statement. If none of the message filters provided with .NET Framework 4 meet your
needs, you can create a custom filter by creating a new implementation of the base
MessageFilter class.When configuring the Routing Service, you must define filter elements
(FilterElement objects) that describe the type of MessageFilter and any supporting data required
to create the filter, such as specific string values to search for within the message. Note that
creating the filter elements only defines the individual message filters; to use the filters to
evaluate and route messages you must also define a filter table (FilterTableEntryCollection).
Each entry in the filter table references a filter element and specifies the client endpoint that a
message will be routed to if the message matches the filter. The filter table entries also allow you
to specify a collection of backup endpoints (BackupEndpointCollection), which defines a list of
endpoints that the message will be transmitted to in the event of a transmission failure when
sending to the primary endpoint. These endpoints will be tried in the order specified until one
succeeds.
Message Filters
The message filters used by the Routing Service provide common message selection
functionality, such as evaluating the name of the endpoint that a message was sent to, the SOAP
action, or the address or address prefix that the message was sent to. Filters can also be joined
with an AND condition, so that messages will only be routed to an endpoint if the message
matches both filters. You can also create custom filters by creating your own implementation of
MessageFilter.The following table lists the FilterType used by the Routing Service, the class
that implements the specific message filter, and the required FilterData parameters.
Filter Type Description
Filter Data
Meaning
Example Filter
Action
Uses the
ActionMessageFilter class
to match messages
containing a specific
action.
The action to
filter upon.
<filter name="action1"
filterType="Action"
filterData="http://namespace/contra
ct/operation" />
EndpointAddres Uses the The address to <filter name="address1"
Resource Links for 70-513 WCF Certification Exam
172
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
s EndpointAddressMessage
Filter class, with
IncludeHostNameInComp
arison == true to match
messages containing a
specific address.
filter upon (in
the To
header).
filterType="EndpointAddress"
filterData="http://host/vdir/s.svc/b"
/>
EndpointAddres
sPrefix
Uses the
PrefixEndpointAddressMe
ssageFilter class, with
IncludeHostNameInComp
arison == true to match
messages containing a
specific address prefix.
The address to
filter upon
using longest
prefix
matching.
<filter name="prefix1"
filterType="EndpointAddressPrefix
" filterData="http://host/" />
And
Uses the
StrictAndMessageFilter
class that always evaluates
both conditions before
returning.
filterData is
not used;
instead filter1
and filter2
have the
names of the
corresponding
message filters
(also in the
table), which
should be
ANDed
together.
<filter name="and1"
filterType="And" filter1="address1"
filter2="action1" />
Custom
A user-defined type that
extends the
MessageFilter class and
has a constructor taking a
The
customType
attribute is the
fully qualified
<filter name="custom1"
filterType="Custom"
customType="CustomAssembly.Cu
stomMsgFilter, CustomAssembly"
Resource Links for 70-513 WCF Certification Exam
173
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
string. type name of
the class to
create;
filterData is
the string to
pass to the
constructor
when creating
the filter.
filterData="Custom Data" />
EndpointName
Uses the
EndpointNameMessageFil
ter class to match
messages based on the
name of the service
endpoint they arrived on.
The name of
the service
endpoint, for
example:
serviceEndpo
int1. This
should be one
of the
endpoints
exposed on
the Routing
Service.
<filter name="stock1"
filterType="Endpoint"
filterData="SvcEndpoint" />
MatchAll
Uses the
MatchAllMessageFilter
class. This filter matches
all arriving messages.
filterData is
not used. This
filter will
always match
all messages.
<filter name="matchAll1"
filterType="MatchAll" />
XPath
Uses the
XPathMessageFilter class
to match specific XPath
queries within the
The XPath
query to use
when
matching
<filter name="XPath1"
filterType="XPath"
filterData="//ns:element" />
Resource Links for 70-513 WCF Certification Exam
174
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
message. messages.
The following example defines filter entries that use the XPath, EndpointName, and
PrefixEndpointAddress message filters. This example also demonstrates using a custom filter for
the RoundRobinFilter1 and RoundRobinFilter2 entries.
XML
<filters>
<filtername="XPathFilter" filterType="XPath"
filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator = 1"/>
<filtername="EndpointNameFilter" filterType="EndpointName"
filterData="calculatorEndpoint"/>
<filtername="PrefixAddressFilter" filterType="PrefixEndpointAddress"
filterData="http://localhost/routingservice/router/rounding/"/>
<filter name="RoundRobinFilter1" filterType="Custom"
customType="RoutingServiceFilters.RoundRobinMessageFilter,
RoutingService" filterData="group1"/>
<filter name="RoundRobinFilter2" filterType="Custom"
customType="RoutingServiceFilters.RoundRobinMessageFilter,
RoutingService" filterData="group1"/>
</filters>
Note:
Simply defining a filter does not cause messages to be evaluated against the filter. The filter must
be added to a filter table, which is then associated with the service endpoint exposed by the
Routing Service.
Namespace Table
When using an XPath filter, the filter data that contains the XPath query can become extremely
large due to the use of namespaces. To alleviate this problem the Routing Service provides the
ability to define your own namespace prefixes by using the namespace table.
The namespace table is a collection of NamespaceElement objects that defines the namespace
prefixes for common namespaces that can be used in an XPath. The following are the default
namespaces and namespace prefixes that are contained in the namespace table.
Prefix Namespace
Resource Links for 70-513 WCF Certification Exam
175
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
s11 http://schemas.xmlsoap.org/soap/envelope
s12 http://www.w3.org/2003/05/soap-envelope
wsaAugust2004 http://schemas.xmlsoap.org/ws/2004/08/addressing
wsa10 http://www.w3.org/2005/08/addressing
sm http://schemas.microsoft.com/serviceModel/2004/05/xpathfunctions
tempuri http://tempuri.org
ser http://schemas.microsoft.com/2003/10/Serialization
When you know that you will be using a specific namespace in your XPath queries, you can add
it to the namespace table along with a unique namespace prefix and use the prefix in any XPath
query instead of the full namespace. The following example defines a prefix of custom for the
namespace http://my.custom.namespace, which is then used in the XPath query contained in
filterData.
XML
<namespaceTable>
<addprefix="custom" namespace="http://my.custom.namespace/"/>
</namespaceTable>
<filters>
<filtername="XPathFilter" filterType="XPath" filterData="/s12:Envelope/s12:Header/custom:RoundingCalculator
= 1"/>
</filters>
Filter Tables
While each filter element defines a logical comparison that can be applied to a message, the filter
table provides the association between the filter element and the destination client endpoint. A
filter table is a named collection of FilterTableEntryElement objects that define the association
between a filter, a primary destination endpoint, and a list of alternative backup endpoints. The
filter table entries also allow you to specify an optional priority for each filter condition. The
following example defines two filters and then defines a filter table that associates each filter
with a destination endpoint.
XML
<routing>
Resource Links for 70-513 WCF Certification Exam
176
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<filters>
<filter name="AddAction" filterType="Action" filterData=Add />
<filter name="SubtractAction" filterType="Action" filterData=Subtract />
</filters>
<filterTables>
<tablename="routingTable1">
<filters>
<addfilterName="AddAction" endpointName="Addition" />
<addfilterName="SubtractAction" endpointName="Subtraction" />
</filters>
</table>
</filterTables>
</routing>
Filter Evaluation Priority
By default, all entries in the filter table are evaluated simultaneously, and the message being
evaluated is routed to the endpoint(s) associated with each matching filter entry. If multiple
filters evaluate to true, and the message is one-way or duplex, the message is multicast to the
endpoints for all matching filters. Request-reply messages cannot be multicast because only one
reply can be returned to the client.More complex routing logic can be implemented by specifying
priority levels for each filter; the Routing Service evaluates all filters at the highest priority level
first. If a message matches a filter of this level, no filters of a lower priority are processed. For
example, an incoming one-way message is first evaluated against all filters with a priority of 2.
The message does not match any filter at this priority level, so next the message is compared
against filters with a priority of 1. Two priority 1 filters match the message, and because it is a
one-way message it is routed to both destination endpoints. Because a match was found among
the priority 1 filters, no filters of priority 0 are evaluated.
Note:
If no priority is specified, the default priority of 0 is used.
The following example defines a filter table that specifies priorities of 2, 1, and 0 for the filters
referenced in the table.
XML
<filterTables>
Resource Links for 70-513 WCF Certification Exam
177
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<filterTablename="filterTable1">
<addfilterName="XPathFilter" endpointName="roundingCalcEndpoint"
priority="2"/>
<addfilterName="EndpointNameFilter" endpointName="regularCalcEndpoint"
priority="1"/>
<addfilterName="PrefixAddressFilter" endpointName="roundingCalcEndpoint"
priority="1"/>
<addfilterName="MatchAllMessageFilter" endpointName="defaultCalcEndpoint"
priority="0"/>
</filterTable>
</filterTables>
In the preceding example, if a message matches the XPathFilter, it will be routed to the
roundingCalcEndpoint and no further filters in the table will be evaluated because all other filters
are of a lower priority. However, if the message does not match the XPathFilter it will then be
evaluated against all filters of the next lower priority, EndpointNameFilter and
PrefixAddressFilter.
Note:
When possible, use exclusive filters instead of specifying a priority because priority evaluation
can result in performance degradation.
Backup Lists
Each filter in the filter table can optionally specify a backup list, which is a named collection of
endpoints (BackupEndpointCollection). This collection contains an ordered list of endpoints
that the message will be transmitted to in the event of a CommunicationException when sending
to the primary endpoint specified in EndpointName. The following example defines a backup list
named backupServiceEndpoints that contains two endpoints.
XML
<filterTables>
<filterTablename="filterTable1">
<addfilterName="MatchAllFilter1" endpointName="Destination" backupList="backupEndpointList"/>
</filterTable>
</filterTables>
<backupLists>
<backupListname="backupEndpointList">
Resource Links for 70-513 WCF Certification Exam
178
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<addendpointName="backupServiceQueue" />
<addendpointName="alternateServiceQueue" />
</backupList>
</backupLists>
In the preceding example, if a send to the primary endpoint Destination fails, the Routing
Service will try sending to each endpoint in the sequence they are listed, first sending to
backupServiceQueue and subsequently sending to alternateServiceQueue if the send to
backupServiceQueue fails. If all backup endpoints fail, a fault is returned.
Routing Scenarios
While the Routing Service is highly customizable, it can be a challenge to design efficient
routing logic when creating a new configuration from scratch. However, there are several
common scenarios that most Routing Service configurations follow. While these scenarios may
not apply directly to your specific configuration, understanding how the Routing Service can be
configured to handle these scenarios will aid you in understanding the Routing Service.
Common Scenarios
The most basic use of the Routing Service is to aggregate multiple destination endpoints to
reduce the number of endpoints exposed to the client applications, and then use message filters to
route each message to the correct destination. Messages may be routed based on logical or
physical processing requirements, such as a message type that must be processed by a specific
service, or based on arbitrary business needs such as providing priority processing of messages
from a specific source. The following table lists some of the common scenarios and when they
are encountered:
Scenario Use when
Service versioning
You need to support multiple versions of a service or may deploy an
updated service in the future
Service data
partitioning
You must partition a service across multiple hosts
Dynamic update
You must dynamically reconfigure routing logic at runtime to handle
changing service deployments
Resource Links for 70-513 WCF Certification Exam
179
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Multicast You must send one message to multiple endpoints
Protocol bridging
You receive messages over one transport protocol, and the destination
endpoint uses a different protocol
Error Handling
You need to provide resilience to network outages and communication
failures
Note:
While many of the scenarios presented are specific to certain business needs or processing requirements,
planning to support dynamic updates and utilizing error handling can often be considered as best practices
as they allow you to modify routing logic at runtime and recover from transient network and
communication failures.
Service Versioning
When introducing a new version of a service, you must often maintain the previous version until
all clients have transitioned to the new service. This is especially critical if the service is a long-
running process that takes days, weeks, or even months to complete. Usually this requires
implementing a new endpoint address for the new service while maintaining the original
endpoint for the previous version.sing the Routing Service, you can expose one endpoint to
receive messages from client applications and then route each message to the correct service
version based on the message content. The most basic implementation involves adding a custom
header to the message that indicates the version of the service that the message is to be processed
by. The Routing Service can use the XPathMessageFilter to inspect each message for the
presence of the custom header and route the message to the appropriate destination endpoint.
For the steps used to create a service versioning configuration, see How To: Service Versioning.
For an example of using the XPathMessageFilter to route messages based on a custom header,
see the Advanced Filters sample.
Service Data Partitioning
When designing a distributed environment, it is often desirable to spread processing load across
multiple computers in order to provide high availability, decrease processing load on individual
computers, or to provide dedicated resources for a specific subset of messages. While the
Routing Service does not replace a dedicated load balancing solution, its ability to perform
content based routing can be used to route otherwise similar messages to specific destinations.
Resource Links for 70-513 WCF Certification Exam
180
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
For example, you may have a requirement to process messages from a specific client separately
from messages received from other clients.For the steps used to create a service data partitioning
configuration, see How To: Service Data Partitioning. For an example of using filters to partition
data based on URL and custom headers, see the Advanced Filters sample.
Dynamic Routing
Often it is desirable to modify the routing configuration to satisfy changing business needs, such
as adding a route to a newer version of a service, changing routing criteria, or changing the
destination endpoint a specific message that the filter routes to. The Routing Service allows you
to do this through the RoutingExtension, which allows you to provide a new
RoutingConfiguration during run time. The new configuration takes effect immediately, but only
affects any new sessions processed by the Routing Service.For the steps used to implement
dynamic routing, see How To: Dynamic Update. For an example of using dynamic routing, see
the Dynamic Reconfiguration sample.
Multicast
When routing messages, usually you routing each message to one specific destination endpoint.
However, you may occasionally need to route a copy of the message to multiple destination
endpoints. To perform multicast routing, the following conditions must be true:
The channel shape must not be request-reply (though it may be one-way or duplex,) because request-reply
mandates that only one reply can be received by the client application in response to the request.
Multiple filters must return true when evaluating the message.
If these conditions are met, each destination endpoint that is associated with a filter that returns
true will receive a copy of the message.For the steps used to configure multicast routing, see
How To: Multicast.
Protocol Bridging
When routing messages between dissimilar SOAP protocols, the Routing Service uses WCF
APIs to convert the message from one protocol to the other. This occurs automatically when the
service endpoint(s) exposed by the Routing Service use a different protocol than the client
endpoint(s) that messages are routed to. It is possible to disable this behavior if the protocols in
use are not standard; however, you must then provide your own bridging code.For the steps used
to configure protocol bridging, see How To: Protocol Translation. For an example of using the
Resource Links for 70-513 WCF Certification Exam
181
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Routing Service to translate messages between protocols, see the Bridging and Error Handling
sample.
Error Handling
In a distributed environment, it is not uncommon to encounter transient network or
communication failures. Without an intermediary service such as the Routing Service, the burden
of handling such failures falls on the client application. If the client application does not include
specific logic to retry in the event of network or communication failures and knowledge of
alternate locations, the user may encounter scenarios where a message must be submitted
multiple times before it is successfully processed by the destination service. This can lead to
customer dissatisfaction with the application, as it may be perceived as unreliable.
The Routing Service attempts to remedy this scenario by providing robust error handling
capabilities for messages that encounter network or communication-related failures. By creating
a list of possible destination endpoints and associating this list with each message filter, you
remove the single point of failure incurred by having only one possible destination. In the event
of a failure, the Routing Service will attempt to deliver the message to the next endpoint in the
list until the message has been delivered, a non-communication failure occurs, or all endpoints
have been exhausted.For the steps used to configure error handling, see How To: Error Handling.
For an example of implementing error handling, see the Bridging and Error Handling and
Advanced Error Handling samples.
In This Section
How To: Service Versioning
How To: Service Data Partitioning
How To: Dynamic Update
How To: Error Handling
Create and configure a Discovery service.This objective may include but is not limited to: configuring ad
hoc and managed modes; Discovery scopes; service announcements
WCF Discovery
Windows Communication Foundation (WCF) provides support to enable 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
Resource Links for 70-513 WCF Certification Exam
182
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
server. Client applications can search the network or a discovery proxy server to find services
that meet a set of criteria. The topics in this section provide an overview and describe the
programming model for this feature in detail.
In This Section
WCF Discovery Overview
Provides an overview of WS-Discovery support provided by WCF.
WCF Discovery Object Model
Describes the classes in the object model and extensibility of WS-Discovery support.
How to: Programmatically Add Discoverability to a WCF Service and Client
Shows how to make a Windows Communication Foundation (WCF) service discoverable.
Implementing a Discovery Proxy
Describes the steps required to implement a discovery proxy, a discoverable service that registers
with the discovery proxy, and a client that uses the discovery proxy to find the discoverable
service.
Discovery Versioning
Provides a brief overview of a prototype implementation of some new discovery features. It also
gives an overview on how to select the discovery version to use.
Configuring Discovery in a Configuration File
Shows how to configure Discovery in configuration.
Using the Discovery Client Channel
Shows how to use a Discovery Client Channel when writing a WCF client application.
WCF Discovery Overview
The Discovery APIs provide a unified programming model for the dynamic publication and
discovery of Web services using the WS-Discovery protocol. These APIs allow services to
publish themselves and clients to find published services. Once a service is made discoverable,
the service has the ability to send announcement messages as well as listen for and respond to
discovery requests. Discoverable services can send Hello messages to announce their arrival on a
network and Bye messages to announce their departure from a network. To find a service, clients
send a Probe request that contains specific criteria such as service contract type, keywords, and
Resource Links for 70-513 WCF Certification Exam
183
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
scope on the network. Services receive the Probe request and determine whether they match the
criteria. If a service matches, it responds by sending a ProbeMatch message back to the client
with the information necessary to contact the service. Clients can also send Resolve requests that
allow them to find services that may have changed their endpoint address. Matching services
respond to Resolve requests by sending a ResolveMatch message back to the client.
Ad-Hoc and Managed Modes
The Discovery API supports two different modes: Managed and Ad-Hoc. In Managed mode
there is a centralized server called a discovery proxy that maintains information about available
services. The discovery proxy can be populated with information about services in a variety of
ways. For example, services can send announcement messages during start up to the discovery
proxy or the proxy may read data from a database or a configuration file to determine what
services are available. How the discovery proxy is populated is completely up to the developer.
Clients use the discovery proxy to retrieve information about available services. When a client
searches for a service it sends a Probe message to the discovery proxy and the proxy determines
whether any of the services it knows about match the service the client is searching for. If there
are matches the discovery proxy sends a ProbeMatch response back to the client. The client can
then contact the service directly using the service information returned from the proxy. The key
principle behind Managed mode is that the discovery requests are sent in a unicast manner to one
authority, the discovery proxy. The .NET Framework contains key components that allow you to
build your own proxy. Clients and services can locate the proxy by multiple methods:
The proxy can respond to ad-hoc messages.
The proxy can send an announcement message during start up.
Clients and services can be written to look for a specific well-known endpoint.
In Ad-Hoc mode, there is no centralized server. All discovery messages such as service
announcements and client requests are sent in a multicast fashion. By default the .NET
Framework contains support for Ad-Hoc discovery over the UDP protocol. For example, if a
service is configured to send out a Hello announcement on start up, it sends it out over a well-
known, multicast address using the UDP protocol. Clients have to actively listen for these
announcements and process them accordingly. When a client sends a Probe message for a
service it is sent over the network using a multicast protocol. Each service that receives the
Resource Links for 70-513 WCF Certification Exam
184
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
request determines whether it matches the criteria in the Probe message and responds directly to
the client with a ProbeMatch message if the service matches the criteria specified in the Probe
message.
Benefits of Using WCF Discovery
Because WCF Discovery is implemented using the WS-Discovery protocol it is interoperable
with other clients, services, and proxies that implement WS-Discovery as well. WCF Discovery
is built upon the existing WCF APIs, which makes it easy to add Discovery functionality to your
existing services and clients. Service discoverability can be easily added through the application
configuration settings. In addition, WCF Discovery also supports using the discovery protocol
over other transports such as peer net, naming overlay, and HTTP. WCF Discovery provides
support for a Managed mode of operation where a discovery proxy is used. This can reduce
network traffic as messages are sent directly to the discovery proxy instead of sending multicast
messages to the entire network. WCF Discovery also allows for more flexibility when working
with Web services. For example, you can change the address of a service without having to
reconfigure the client or the service. When a client must access the service it can issue a Probe
message through a Find request and expect the service to respond with its current address. WCF
Discovery allows a client to search for a service based on different criteria including contract
types, binding elements, namespace, scope, and keywords or version numbers. WCF Discovery
enables runtime and design time discovery. Adding discovery to your application can be used to
enable other scenarios such as fault tolerance and auto configuration.
Service Publication
To make a service discoverable, a ServiceDiscoveryBehavior must be added to the service host
and a discovery endpoint must be added to specify where to listen for discovery messages. The
following code example shows how a self-hosted service can be modified to make it
discoverable.
Uri baseAddress = new Uri(string.Format("http://{0}:8000/discovery/scenarios/calculatorservice/{1}/",
System.Net.Dns.GetHostName(), Guid.NewGuid().ToString()));
// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
// add calculator endpoint
Resource Links for 70-513 WCF Certification Exam
185
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
serviceHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), string.Empty);
// ** DISCOVERY ** //
// make the service discoverable by adding the discovery behavior
serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
// ** DISCOVERY ** //
// add the discovery endpoint that specifies where to publish the services
serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("Press <ENTER> to terminate service.");
Console.ReadLine();
}
A ServiceDiscoveryBehavior instance must be added to a service description for the service to
be discoverable. A DiscoveryEndpoint instance must be added to the service host to tell the
service where to listen for discovery requests. In this example, a UdpDiscoveryEndpoint (which
is derived from DiscoveryEndpoint) is added to specify that the service should listen for
discovery requests over the UDP multicast transport. The UdpDiscoveryEndpoint is used for
Ad-Hoc discovery because all messages are sent in a multicast fashion.
Announcement
By default, service publication does not send out announcement messages. The service must be
configured to send out announcement messages. This provides additional flexibility for service
writers because they can announce the service separately from listening for discovery messages.
Service announcement can also be used as a mechanism for registering services with a discovery
proxy or other service registries. The following code shows how to configure a service to send
announcement messages over a UDP binding.
Uri baseAddress = new Uri(string.Format("http://{0}:8000/discovery/scenarios/calculatorservice/{1}/",
System.Net.Dns.GetHostName(), Guid.NewGuid().ToString()));
// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
// add calculator endpoint
serviceHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), string.Empty);
// ** DISCOVERY ** //
Resource Links for 70-513 WCF Certification Exam
186
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
// make the service discoverable by adding the discovery behavior
ServiceDiscoveryBehavior discoveryBehavior = new ServiceDiscoveryBehavior();
serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());

// send announcements on UDP multicast transport
discoveryBehavior.AnnouncementEndpoints.Add( new UdpAnnouncementEndpoint());
// ** DISCOVERY ** //
// add the discovery endpoint that specifies where to publish the services
serviceHost.Description.Endpoints.Add(new UdpDiscoveryEndpoint());
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("Press <ENTER> to terminate service.");
Console.ReadLine();
}
Service Discovery
A client application can use the DiscoveryClient class to find services. The developer creates an
instance of the DiscoveryClient class that passes in a discovery endpoint that specifies where to
send Probe or Resolve messages. The client then calls Find that specifies search criteria within a
FindCriteria instance. If matching services are found, Find returns a collection of
EndpointDiscoveryMetadata. The following code shows how to call the Find method and then
connect to a discovered service.
class Client
{
static EndpointAddress serviceAddress;
static void Main()
{
if (FindService()) InvokeService();
}
// ** DISCOVERY ** //
static bool FindService()
{
Console.WriteLine("\nFinding Calculator Service ..");
DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
Resource Links for 70-513 WCF Certification Exam
187
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Collection<EndpointDiscoveryMetadata> calculatorServices = discoveryClient.Find(new
FindCriteria(typeof(ICalculator)));
discoveryClient.Close();
if (calculatorServices.Count == 0)
{
Console.WriteLine("\nNo services are found.");
return false;
}
else
{
serviceAddress = calculatorServices[0].EndpointAddress;
return true;
}
}
static void InvokeService()
{
Console.WriteLine("\nInvoking Calculator Service at {0}\n", serviceAddress);
// Create a client
CalculatorClient client = new CalculatorClient();
client.Endpoint.Address = serviceAddress;
client.Add(10,3);
}
Discovery and Message Level Security
When using message level security it is necessary to specify an EndpointIdentity on the service
discovery endpoint and a matching EndpointIdentity on the client discovery endpoint. For more
information about message level security, see Message Security in WCF.
Discovery and Web Hosted Services
In order for WCF services to be discoverable they must be running. WCF services hosted under
IIS or WAS do not run until IIS/WAS receives a message bound for the service, so they cannot
be discoverable by default. There are two options for making Web-Hosted services discoverable:
1. Use the Windows Server AppFabric Auto-Start feature
2. Use a discovery proxy to communicate on behalf of the service
Resource Links for 70-513 WCF Certification Exam
188
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Windows Server AppFabric has an Auto-Start feature that will allow a service to be started
before receiving any messages. With this Auto-Start set, an IIS/WAS hosted service can be
configured to be discoverable. For more information about the Auto-Start feature see, Windows
Server AppFabric Auto-Start Feature. Along with turning on the Auto-Start feature, you must
configure the service for discovery. For more information, see How to: Programmatically Add
Discoverability to a WCF Service and ClientConfiguring Discovery in a Configuration File.
A discovery proxy can be used to communicate on behalf of the WCF service when the service is
not running. The proxy can listen for probe or resolve messages and respond to the client. The
client can then send messages directly to the service. When the client sends a message to the
service it will be instantiated to respond to the message. For more information about
implementing a discovery proxy see, Implementing a Discovery Proxy.
WCF Discovery Object Model
WCF Discovery consists of a set of types that provide a unified programming model that allows
you to write services that are discoverable at runtime and clients that find and use these services.
Making a Service Discoverable and Finding Services
To make a WCF service discoverable, add a ServiceDiscoveryBehavior to the
ServiceDescription of the service host and add a discovery endpoint. If a service is configured to
send announcement messages (by adding an AnnouncementEndpoint) the announcement is sent
when the service host is opened and closed. A client that wants to listen for service
announcement messages hosts an announcement service and adds one or more announcement
endpoints. The announcement service receives announcement messages and raises
announcement events.A client uses the DiscoveryClient class to search for available services.
The client application instantiates the DiscoveryClient class, passing in a discovery endpoint
that specifies where to send discovery messages. The client calls the Find method, which sends a
Probe request. Services listening for discovery messages receive this Probe request. If the
service matches the criteria specified in the Probe, it sends a ProbeMatch message back to the
client.
Object Model
The WCF Discovery API defines the following classes:
Resource Links for 70-513 WCF Certification Exam
189
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
AnnouncementClient
AnnouncementEndpoint
AnnouncementService
DiscoveryClient
DiscoveryEndpoint
DiscoveryClientBindingElement
DiscoveryMessageSequenceGenerator
ServiceDiscoveryMode
DiscoveryProxy
DiscoveryService
DiscoveryVersion
DynamicEndpoint
EndpointDiscoveryBehavior
EndpointDiscoveryMetadata
FindCriteria
FindRequestContext
FindResponse
ResolveCriteria
ResolveResponse
ServiceDiscoveryBehavior
ServiceDiscoveryExtension
UdpAnnouncementEndpoint
UdpDiscoveryEndpoint
AnnouncementClient
The AnnouncementClient class provides synchronous and asynchronous methods for sending
announcement messages. There are two types of announcement messages, Hello and Bye. A
Hello message is sent to indicate that a service has become available and a Bye message is sent
to indicate that an existing service has become unavailable. The developer creates an
AnnouncementClient instance, passing an instance of AnnouncementEndpoint as a
constructor parameter.
AnnouncementEndpoint
Resource Links for 70-513 WCF Certification Exam
190
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
AnnouncementEndpoint represents a standard endpoint with a fixed announcement contract. It
is used by a service or client to send and receive announcement messages. By default, the
AnnouncementEndpoint class is set to use the WS_Discovery 11 protocol version.
AnnouncementService
AnnouncementService is a system-provided implementation of an announcement service that
receives and processes announcement messages. When a Hello or Bye message is received, the
AnnouncementService instance calls the appropriate virtual method
OnBeginOnlineAnnouncement or OnBeginOfflineAnnouncement, which raises announcement
events.
DiscoveryClient
The DiscoveryClient class is used by a client application to find and resolve available services.
It provides synchronous and asynchronous methods for finding and resolving services based on
the specified FindCriteria and ResolveCriteria respectively. The developer creates a
DiscoveryClient instance and provides an instance of DiscoveryEndpoint as a constructor
parameter.
To find a service, the developer invokes the synchronous or asynchronous Find method, which
provides a FindCriteria instance that contains the search criteria to use. The DiscoveryClient
creates a Probe message with the appropriate headers, and sends the find request. Because there
can be more than one outstanding Find request at any time, the client correlates the received
responses and validates the response. It then delivers the results to the caller of the Find
operation using FindResponse.To resolve a known service, the developer invokes the
synchronous or asynchronous Resolve method that provides an instance of ResolveCriteria that
contains the EndpointAddress of the known service. The DiscoveryClient creates the Resolve
message with the appropriate headers and sends the resolve request. The received response is
correlated against the outstanding resolve requests and the result is delivered to the caller of the
Resolve operation using ResolveResponse. If a discovery proxy is present on the network and
the DiscoveryClient sends the discovery request in a multicast fashion, the discovery proxy can
respond with the multicast suppression Hello message. The DiscoveryClient raises the
ProxyAvailable event when it receives Hello messages in response to outstanding Find or
Resolve requests. The ProxyAvailable event contains the EndpointDiscoveryMetadata about
Resource Links for 70-513 WCF Certification Exam
191
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
the discovery proxy. It is up to the developer to use this information to switch from Ad hoc to
Managed mode.
DiscoveryEndpoint
DiscoveryEndpoint represents a standard endpoint with a fixed discovery contract. It is used by
a service or client to send or receive discovery messages. By default, DiscoveryEndpoint is set
to use Managed mode and the WSDiscovery11 WS-Discovery version.
DiscoveryMessageSequenceGenerator
DiscoveryMessageSequenceGenerator is used to generate a DiscoveryMessageSequence when
the service is sending out Discovery or Announcement messages.
DiscoveryService
The DiscoveryService abstract class provides a framework for receiving and processing Probe
and Resolve messages. When a Probe message is received, DiscoveryService creates an
instance of FindRequestContext based on the incoming message and invokes the OnBeginFind
virtual method. When a Resolve message is received, DiscoveryService invokes the
OnBeginResolve virtual method. You can inherit from this class to provide a custom Discovery
Service implementation.
DiscoveryProxy
The DiscoveryProxy abstract class provides a framework for receiving and processing discovery
and announcement messages. You inherit from this class when you are implementing a custom
discovery proxy. When a Probe message is received over multicast, the DiscoveryProxy class
calls the BeginShouldRedirectFind virtual method to determine whether a multicast
suppression message should to be sent. If the developer decides not to send a multicast
suppression message or if the Probe message was received over unicast, it creates an instance of
the FindRequestContext class based on the incoming message and invokes the OnBeginFind
virtual method. When a Resolve message is received over multicast, The DiscoveryProxy class
calls the ShouldRedirectResolve virtual method to determine whether a multicast suppression
message should to be sent. If the developer decides not to send a multicast suppression message
or if the Resolve message was received over unicast, it creates an instance of the
ResolveCriteria class based on the incoming message and invokes the OnBeginResolve virtual
Resource Links for 70-513 WCF Certification Exam
192
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
method. When a Hello or Bye message is received, DiscoveryProxy calls the appropriate virtual
method (OnBeginOnlineAnnouncement or OnBeingOfflineAnnouncement), which raises
announcement events.
DiscoveryVersion
The DiscoveryVersion class represents the discovery protocol version to use.
EndpointDiscoveryBehavior
The EndpointDiscoveryBehavior class is used to control the discoverability of an endpoint,
specify the extensions, additional contract type names. and the scopes associated with that
endpoint. This behavior is added to an application endpoint to configure its
EndpointDiscoveryMetadata. When ServiceDiscoveryBehavior is added to the service host,
all the application endpoints hosted by the service host by default become discoverable. The
developer can turn off discovery for a specific endpoint by setting the Enable property to false.
EndpointDiscoveryMetadata
The EndpointDiscoveryMetadata class provides a version-independent representation of an
endpoint published by the service. It contains endpoint addresses, listen URIs, contract type
names, scopes, metadata version and extensions specified by the service developer. The
FindCriteria sent by the client during a Probe operation is matched against the
EndpointDiscoveryMetadata. If the criteria matches, then the EndpointDiscoveryMetadata is
returned to the client. The endpoint address in ResolveCriteria is matched against the endpoint
address of EndpointDiscoveryMetadata. If the criteria matches, then the
EndpointDiscoveryMetadata is returned to the client.
FindCriteria
The FindCriteria class is a version-independent class used to specify the criteria used when
finding a service. It fully supports the WS-Discovery-defined criteria for matching services. It
also has extensions that developers can use to specify custom values that can be used during the
matching process. The developer can provide the termination criteria for the Find operation by
specifying the MaxResult, which specifies the total number of services the developer is looking
for or that specifies the Duration, which is the value that specifies how long the client waits for
responses.
Resource Links for 70-513 WCF Certification Exam
193
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
FindRequestContext
The FindRequestContext class is instantiated by the discovery service based on the Probe
message it receives when a client initiates a Find operation. It contains an instance of
FindCriteria that was specified by the client.
FindResponse
The FindResponse class is returned to the caller of Find with the responses of the Find
operation. It is also present in FindCompletedEventArgs. It contains a collection of
EndpointDiscoveryMetadata, which is the collection of discovered endpoints and a dictionary
of EndpointDiscoveryMetadata and DiscoveryMessageSequence.
ResolveCriteria
The ResolveCriteria class is a version-independent class used to specify the criteria used when
resolving an already known service. It contains the endpoint address of the known service. The
developer can provide the termination criteria for the resolve operation by specifying the
Duration, which specifies how long the client waits for responses.
ResolveResponse
The ResolveResponse is returned to the caller of the Resolve method with the response of the
Resolve operation. It is also present in ResolveCompletedEventArgs. It contains an instance of
EndpointDiscoveryMetadata, which is the discovered endpoints and an instance of
DiscoveryMessageSequence.
ServiceDiscoveryBehavior
The ServiceDiscoveryBehavior class allows the developer to add the discovery feature to a
service. You add this behavior to the ServiceHost. The ServiceDiscoveryBehavior class iterates
over the application endpoints added to the service host and creates a collection of
EndpointDiscoveryMetadata from the discoverable endpoints. All endpoints are discoverable
by default. The discoverability of a particular endpoint can be controlled by adding the
EndpointDiscoveryBehavior to that particular endpoint. If announcement endpoints are added
to ServiceDiscoveryBehavior then the announcement of all discoverable endpoints is sent over
each of the announcement endpoints when the service host is opened or closed.
Resource Links for 70-513 WCF Certification Exam
194
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
ServiceDiscoveryExtension
The ServiceDiscoveryExtension class is created by the ServiceDiscoveryBehavior class. The
endpoints that are made discoverable can be obtained from ServiceDiscoveryExtension. This
class is also used to specify a custom discovery service implementation.
UdpAnnouncementEndpoint
The UdpAnnouncementEndpoint class is a standard announcement endpoint that is pre-
configured for announcement over a UDP multicast binding. By default,
UdpAnnouncementEndpoint is set to use the WSApril2005 WS_Discovery version.
UdpDiscoveryEndpoint
The UdpDiscoveryEndpoint class is a standard discovery endpoint that is pre-configured for
discovery over a UDP multicast binding. By default, DiscoveryEndpoint is set to use the
WSDiscovery11 WS-Discovery version and Adhoc mode.
How to: Programmatically Add
Discoverability to a WCF Service and Client
This topic explains how to make a Windows Communication Foundation (WCF) service
discoverable. It is based on the Self-Host sample.
To configure the existing Self-Host service sample for
Discovery
1. Open the Self-Host solution in Visual Studio 2010. The sample is located in the
TechnologySamples\Basic\Service\Hosting\SelfHost directory.
2. Add a reference to System.ServiceModel.Discovery.dll to the service project. You may see an error
message saying System. ServiceModel.Discovery.dll or one of its dependencies requires a later
version of the .NET Framework than the one specified in the project If you see this message,
right-click the project in the Solution Explorer and choose Properties. In the Project Properties
window, make sure that the Target Framework is .NET Framework version 4.
3. Open the Service.cs file and add the following using statement.
Resource Links for 70-513 WCF Certification Exam
195
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
4. using System.ServiceModel.Discovery;
5. In the Main() method, inside the using statement, add a ServiceDiscoveryBehavior instance to the
service host.
6. public static void Main()
7. {
8. // Create a ServiceHost for the CalculatorService type.
9. using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
10. {
11. // Add a ServiceDiscoveryBehavior
12. serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
13. // ...
14. }
15. }
The ServiceDiscoveryBehavior specifies that the service it is applied to is discoverable.
16. Add a UdpDiscoveryEndpoint to the service host right after the code that adds the
ServiceDiscoveryBehavior.
17. // Add ServiceDiscoveryBehavior
18. serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
19. // Add a UdpDiscoveryEndpoint
20. serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
This code specifies that discovery messages should be sent to the standard UDP discovery
endpoint.
To create a client application that uses discovery to call the
service
Add a new console application to the solution called DiscoveryClientApp.
Add a reference to System.ServiceModel.dll and System.ServiceModel.Discovery.dll
Copy the GeneratedClient.cs and App.config files from the existing client project to the new
DiscoveryClientApp project. To do this, right-click the files in the Solution Explorer, select
Copy, and then select the DiscoveryClientApp project, right-click and select Paste.
Open Program.cs.
Add the following using statements.
using System.ServiceModel;
Resource Links for 70-513 WCF Certification Exam
196
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
using System.ServiceModel.Discovery;
using Microsoft.ServiceModel.Samples;
Add a static method called FindCalculatorServiceAddress() to the Program class.
static EndpointAddress FindCalculatorServiceAddress(){}
This method uses discovery to search for the CalculatorService service.
Inside the FindCalculatorServiceAddress method, create a new DiscoveryClient instance, passing in a
UdpDiscoveryEndpoint to the constructor.
static EndpointAddress FindCalculatorServiceAddress()
{
// Create DiscoveryClient
DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
}
This tells WCF that the DiscoveryClient class should use the standard UDP discovery endpoint
to send and receive discovery messages.
On the next line, call the Find method and specify a FindCriteria instance that contains the
service contract you want to search for. In this case, specify ICalculator.
// Find ICalculatorService endpoints
FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
After the call to Find, check to see if there is at least one matching service and return the
EndpointAddress of the first matching service. Otherwise return null.
if (findResponse.Endpoints.Count > 0)
{
return findResponse.Endpoints[0].Address;
}
else
{
return null;
}
Add a static method named InvokeCalculatorService to the Program class.
static void InvokeCalculatorService(EndpointAddress endpointAddress)
{
}
This method uses the endpoint address returned from FindCalculatorServiceAddress to call the
calculator service.
Resource Links for 70-513 WCF Certification Exam
197
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Inside the InvokeCalculatorService method, create an instance of the CalculatorServiceClient class. This
class is defined by the Self-Host sample. It was generated using Svcutil.exe.
// Create a client
CalculatorClient client = new CalculatorClient();
On the next line, set the endpoint address of the client to the endpoint address returned from
FindCalculatorServiceAddress().
// Connect to the discovered service endpoint
client.Endpoint.Address = endpointAddress;
Immediately after the code for the previous step, call the methods exposed by the calculator
service.
Console.WriteLine("Invoking CalculatorService at {0}", endpointAddress);
double value1 = 100.00D;
double value2 = 15.99D;
// Call the Add service operation.
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
// Call the Subtract service operation.
result = client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
// Call the Multiply service operation.
result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
// Call the Divide service operation.
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
Console.WriteLine();
//Closing the client gracefully closes the connection and cleans up resources
client.Close();
Add code to the Main() method in the Program class to call FindCalculatorServiceAddress.
public static void Main()
{
EndpointAddress endpointAddress = FindCalculatorServiceAddress();
}
On the next line, call the InvokeCalculatorService() and pass in the endpoint address returned from
FindCalculatorServiceAddress().
Resource Links for 70-513 WCF Certification Exam
198
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
if (endpointAddress != null)
{
InvokeCalculatorService(endpointAddress);
}
Console.WriteLine("Press <ENTER> to exit.");
Console.ReadLine();
To test the application
1. Open an elevated command prompt and run Service.exe.
2. Open a command prompt and run Discoveryclientapp.exe.
3. The output from service.exe should look like the following output.
4. Received Add(100,15.99)
5. Return: 115.99
6. Received Subtract(100,15.99)
7. Return: 84.01
8. Received Multiply(100,15.99)
9. Return: 1599
10. Received Divide(100,15.99)
Return: 6.25390869293308
11. The output from Discoveryclientapp.exe should look like the following output.
12. Invoking CalculatorService at http://localhost:8000/ServiceModelSamples/service
13. Add(100,15.99) = 115.99
14. Subtract(100,15.99) = 84.01
15. Multiply(100,15.99) = 1599
16. Divide(100,15.99) = 6.25390869293308
Press <ENTER> to exit.
Example
The following is a listing of the code for this sample. Because this code is based on the Self-Host
sample, only those files that are changed are listed. For more information about the Self-Host
sample, see Setup Instructions.
// Service.cs
using System;
using System.Configuration;
using System.ServiceModel;
using System.ServiceModel.Discovery;
Resource Links for 70-513 WCF Certification Exam
199
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
namespace Microsoft.ServiceModel.Samples
{
// See SelfHost sample for service contract and implementation
// ...
// Host the service within this EXE console application.
public static void Main()
{
// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService)))
{
// Add the ServiceDiscoveryBehavior to make the service discoverable
serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
}
}
}
}
// Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Discovery;
using Microsoft.ServiceModel.Samples;
using System.Text;
namespace DiscoveryClientApp
{
class Program
{
static EndpointAddress FindCalculatorServiceAddress()
Resource Links for 70-513 WCF Certification Exam
200
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
{
// Create DiscoveryClient
DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());

// Find ICalculatorService endpoints
FindResponse findResponse = discoveryClient.Find(new FindCriteria(typeof(ICalculator)));
if (findResponse.Endpoints.Count > 0)
{
return findResponse.Endpoints[0].Address;
}
else
{
return null;
}
}
static void InvokeCalculatorService(EndpointAddress endpointAddress)
{
// Create a client
CalculatorClient client = new CalculatorClient();
// Connect to the discovered service endpoint
client.Endpoint.Address = endpointAddress;
Console.WriteLine("Invoking CalculatorService at {0}", endpointAddress);
double value1 = 100.00D;
double value2 = 15.99D;
// Call the Add service operation.
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
// Call the Subtract service operation.
result = client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
// Call the Multiply service operation.
result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
// Call the Divide service operation.
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
Console.WriteLine();
Resource Links for 70-513 WCF Certification Exam
201
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
//Closing the client gracefully closes the connection and cleans up resources
client.Close();
}
static void Main(string[] args)
{
EndpointAddress endpointAddress = FindCalculatorServiceAddress();
if (endpointAddress != null)
{
InvokeCalculatorService(endpointAddress);
}
Console.WriteLine("Press <ENTER> to exit.");
Console.ReadLine();
}
}
}
Implementing a Discovery Proxy
This section describes the steps required to implement a discovery proxy. A discovery proxy is a
standalone service that contains a repository of services. Clients can query a discovery proxy to
find discoverable services that the proxy is aware of. How a proxy is populated with services is
up to the implementer. For example, a discovery proxy can connect to an existing service
repository and make that information discoverable, an administrator can use a management API
to add discoverable services to a proxy, or a discovery proxy can use the announcement
functionality to update its internal cache. The WCF implementation provides base classes that
allow you to easily build a proxy. You can utilize these APIs to build a Discovery Proxy on top
of your existing repository.The discovery proxy implemented here is like any other WCF
services, in that you can also make the discovery proxy discoverable and have the clients locate
its endpoints.
In This Section
How to: Implement a Discovery Proxy
Describes how to implement a discovery proxy.
How to: Implement a Discoverable Service that Registers with the Discovery Proxy
Describes how to implement a discoverable WCF service that registers with the discovery proxy.
Resource Links for 70-513 WCF Certification Exam
202
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
How to: Implement a Client Application that Uses the Discovery Proxy to Find a Service
Describes how to implement a WCF client application that uses the discovery proxy to search for
a service.
How to: Test the Discovery Proxy
Describes how to test the code written in the previous three topics.
Discovery Versioning
This topic provides a brief overview of the implementation of some new discovery features. It
also gives an overview on how to select the discovery version to use.
Discovery Versioning
The discovery feature includes support for three versions of the WS_Discovery protocol. The
discovery APIs allow you to select which version of the protocol you want to use. This document
briefly describes the versioning-related settings.
The following Discovery classes now have a DiscoveryVersion property and take a
DiscoveryVersion argument in their constructors:
AnnouncementEndpoint
DiscoveryEndpoint
UdpDiscoveryEndpoint
UdpAnnouncementEndpoint
DiscoveryVersion.WSDiscoveryApril2005
ProvidingWSDiscoveryApril2005 as a constructor parameter makes the implementation use the
April2005 version of the WS-Discovery protocol. This version corresponds to the published
version of the WS-Discovery protocol specification. This version should be used to interoperate
with legacy application utilizing the April2005 version of WS-Discovery.
DiscoveryVersion.WSDiscovery11
The default discovery version used by the APIs isWSDiscovery11. This is the current
standardized version of the WS-Discovery protocol.
DiscoveryVersion.WSDiscoveryCD1
Providing WSDiscoveryCD1 as a constructor parameter makes the implementation use the
committee draft 1 version of the WS-Discovery protocol. This version of the protocol should be
Resource Links for 70-513 WCF Certification Exam
203
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
used to interoperate with implementations running the CD1 version of the WS-Discovery
protocol.
Supporting Multiple UDP Discovery Endpoints for Different
Discovery Versions on a Single Service Host
You may want to expose multiple UDP Discovery Endpoints for different discovery versions on
a single service host. To do this you must specify a unique address for each UDP discovery
endpoint. The following example shows how to do this.
UdpDiscoveryEndpoint newVersionUdpEndpoint = new
UdpDiscoveryEndpoint(DiscoveryVersion.WSDiscovery11);
UdpDiscoveryEndpoint oldVersionUdpEndpoint = new
UdpDiscoveryEndpoint(DiscoveryVersion.WSDiscoveryApril2005);
newVersionUdpEndpoint.Address = new EndpointAddress(newVersionUdpEndpoint.Address.Uri.ToString() +
"/version11");
oldVersionUdpEndpoint.Address = new EndpointAddress(oldVersionUdpEndpoint.Address.Uri.ToString() +
"/versionAril2005");
serviceHost.AddServiceEndpoint(newVersionUdpEndpoint);
serviceHost.AddServiceEndpoint(oldVersionUdpEndpoint);
Discovery Versioning
This topic provides a brief overview of the implementation of some new discovery features. It
also gives an overview on how to select the discovery version to use.
Discovery Versioning
The discovery feature includes support for three versions of the WS_Discovery protocol. The
discovery APIs allow you to select which version of the protocol you want to use. This document
briefly describes the versioning-related settings.
The following Discovery classes now have a DiscoveryVersion property and take a
DiscoveryVersion argument in their constructors:
AnnouncementEndpoint
DiscoveryEndpoint
UdpDiscoveryEndpoint
UdpAnnouncementEndpoint
Resource Links for 70-513 WCF Certification Exam
204
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
DiscoveryVersion.WSDiscoveryApril2005
ProvidingWSDiscoveryApril2005 as a constructor parameter makes the implementation use the
April2005 version of the WS-Discovery protocol. This version corresponds to the published
version of the WS-Discovery protocol specification. This version should be used to interoperate
with legacy application utilizing the April2005 version of WS-Discovery.
DiscoveryVersion.WSDiscovery11
The default discovery version used by the APIs isWSDiscovery11. This is the current
standardized version of the WS-Discovery protocol.
DiscoveryVersion.WSDiscoveryCD1
Providing WSDiscoveryCD1 as a constructor parameter makes the implementation use the
committee draft 1 version of the WS-Discovery protocol. This version of the protocol should be
used to interoperate with implementations running the CD1 version of the WS-Discovery
protocol.
Supporting Multiple UDP Discovery Endpoints for Different
Discovery Versions on a Single Service Host
You may want to expose multiple UDP Discovery Endpoints for different discovery versions on
a single service host. To do this you must specify a unique address for each UDP discovery
endpoint. The following example shows how to do this.
UdpDiscoveryEndpoint newVersionUdpEndpoint = new
UdpDiscoveryEndpoint(DiscoveryVersion.WSDiscovery11);
UdpDiscoveryEndpoint oldVersionUdpEndpoint = new
UdpDiscoveryEndpoint(DiscoveryVersion.WSDiscoveryApril2005);
newVersionUdpEndpoint.Address = new EndpointAddress(newVersionUdpEndpoint.Address.Uri.ToString() +
"/version11");
oldVersionUdpEndpoint.Address = new EndpointAddress(oldVersionUdpEndpoint.Address.Uri.ToString() +
"/versionAril2005");
serviceHost.AddServiceEndpoint(newVersionUdpEndpoint);
serviceHost.AddServiceEndpoint(oldVersionUdpEndpoint);
Using the Discovery Client Channel
Resource Links for 70-513 WCF Certification Exam
205
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
When writing a WCF client application you need to know the endpoint address of the service
you are calling. In many situations the endpoint address of a service is not known in advance or
the address of the service changes over time. The Discovery Client Channel allows you to write a
WCF client application, describe the service you want to call, and the client channel
automatically sends a probe request. When a service responds, the discovery client channel
retrieves the endpoint address for the service from the probe response and uses it to call the
service.
Using the Discovery Client Channel
To use the Discovery Client Channel, add an instance of the DiscoveryClientBindingElement to
your client channel stack. Alternatively you can use the DynamicEndpoint and a
DiscoveryClientBindingElement is automatically added to your binding if not already present.
Caution:
It is recommended that the DiscoveryClientBindingElement is the top-most element on your client
channel stack. Any binding element that is added on top of the DiscoveryClientBindingElement must
make sure that the ChannelFactory or channel it creates does not use the endpoint address or Via address
(passed to the CreateChannel method) because they may not contain the correct address.
The DiscoveryClientBindingElement class contains two public properties:
1. FindCriteria, which is used to describe the service you want to call.
2. DiscoveryEndpoint, which specifies the discovery endpoint to send discovery messages to.
The FindCriteria property allows you to specify the service contract you are searching for, any
required scope URIs, and the maximum number of time to attempt to open the channel. The
contract type is specified by calling the constructor FindCriteria. Scope URIs can be added to the
Scopes property. The MaxResults property allows you to specify the maximum number of results
to which the client tries to connect to. When a probe response is received the client attempts to
open the channel using the endpoint address from the probe response. If an exception occurs the
client moves on to the next probe response, waiting for more responses to be received if
necessary. It continues to do this until the channel is successfully opened or the maximum
number of results is reached. For more information aboutthese settings, see FindCriteria.
The DiscoveryEndpoint property allows you to specify the discovery endpoint to use. Normally
this is a UdpDiscoveryEndpoint, but it can be any valid endpoint.When you are creating the
Resource Links for 70-513 WCF Certification Exam
206
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
binding to use to communicate with the service, you must be careful to use the exact same
binding as the service. The only difference is the client binding has a
DiscoveryClientBindingElement on the top of the stack. If service is using one of the system-
provided bindings, create a new CustomBinding and pass in the system-provided binding to the
CustomBinding constructor. Then you can add the DiscoveryClientBindingElement by calling
Insert on the Elements property. Once you have added the DiscoveryClientBindingElement to
your binding and configured it, you can create an instance of the WCF client class, open it, and
call its methods. The following example uses the Discovery Client Channel to discover a WCF
service that implements the ICalculator class (used in the Getting Started WCF tutorial) and calls
its Add method.
// Create the DiscoveryClientBindingElement
DiscoveryClientBindingElement bindingElement = new DiscoveryClientBindingElement();
// Search for a service that implements the ICalculator interface, attempting to open
// the channel a maximum of 2 times
bindingElement.FindCriteria = new FindCriteria(typeof(ICalculator)) { MaxResults = 2 };
// Use the UdpDiscoveryEndpoint
bindingElement.DiscoveryEndpoint = new UdpDiscoveryEndpoint();
// The service uses the BasicHttpBinding, so use that and insert the DiscoveryClientBindingElement at the
// top of the stack
CustomBinding binding = new CustomBinding(new BasicHttpBinding());
binding.Elements.Insert(0,bindingElement);
try
{
// Create the WCF client and call a method
CalculatorClient client = new CalculatorClient(binding, new
EndpointAddress("http://schemas.microsoft.com/dynamic"));
client.Open();
client.Add(1, 1);
}
catch (EndpointNotFoundException ex)
{
Console.WriteLine("An exception occurred: " + ex.Message);
}
Security and the Discovery Client Channel
Resource Links for 70-513 WCF Certification Exam
207
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
When using the discovery client channel, two endpoints are being specified. One is used for
discovery messages, usually UdpDiscoveryEndpoint, and the other is the application endpoint.
When implementing a secure service, care must be taken to secure both endpoints. For more
information about security, see Securing Services and Clients.
Hosting and Configuring Services (18%)
Create and configure endpoints.This objective may include but is not limited to: default and
standard bindings; custom bindings created from standard binding elements; standard endpoints;
transports including HTTP, TCP, named pipes, UDP, MSMQ code-based service configuration;
message encodingThis objective does not include: creating a custom binding element; creating
new standard endpoints, loading configuration from a location other than the default application
configuration file, security, transaction, reliable sessions
Endpoints: Addresses, Bindings, and
Contracts
All communication with a Windows Communication Foundation (WCF) service occurs through
the endpoints of the service. Endpoints provide clients access to the functionality offered by a
WCF service. Each endpoint consists of four properties:
An address that indicates where the endpoint can be found.
A binding that specifies how a client can communicate with the endpoint.
A contract that identifies the operations available.
A set of behaviors that specify local implementation details of the endpoint.
This topic discusses this endpoint structure and explains how it is represented in the WCF object
model.
The Structure of an Endpoint
Each endpoint consists of the following:
Address: The address uniquely identifies the endpoint and tells potential consumers of the
service where it is located. It is represented in the WCF object model by the EndpointAddress
class. An EndpointAddress class contains:
A Uri property, which represents the address of the service.
An Identity property, which represents the security identity of the service and a collection of
optional message headers. The optional message headers are used to provide additional and more
detailed addressing information to identify or interact with the endpoint.
For more information, see Specifying an Endpoint Address.
Binding: The binding specifies how to communicate with the endpoint. This includes:
The transport protocol to use (for example, TCP or HTTP).
The encoding to use for the messages (for example, text or binary).
The necessary security requirements (for example, SSL or SOAP message security).
For more information, see Windows Communication Foundation Bindings Overview. A binding
is represented in the WCF object model by the abstract base class Binding. For most scenarios,
users can use one of the system-provided bindings. For more information, see System-Provided
Bindings.
Resource Links for 70-513 WCF Certification Exam
208
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Contracts: The contract outlines what functionality the endpoint exposes to the client. A contract
specifies:
What operations can be called by a client.
The form of the message.
The type of input parameters or data required to call the operation.
What type of processing or response message the client can expect.
For more information about defining a contract, see Designing Service Contracts.
Behaviors: You can use endpoint behaviors to customize the local behavior of the service
endpoint. Endpoint behaviors achieve this by participating in the process of building a WCF
runtime. An example of an endpoint behavior is the ListenUri property, which allows you to
specify a different listening address than the SOAP or Web Services Description Language
(WSDL) address. For more information, see ClientViaBehavior.
Defining Endpoints
You can specify the endpoint for a service either imperatively using code or declaratively
through configuration. For more information, see How to: Create a Service Endpoint in
Configuration and How to: Create a Service Endpoint in Code.
In This Section
This section explains the purpose of bindings, endpoints, and addresses; shows how to configure
a binding and an endpoint; and demonstrates how to use the ClientVia behavior and ListenUri
property.
Endpoint Addresses
Describes how endpoints are addressed in WCF.
Windows Communcation Foundation Bindings
Describes how bindings are used to specify the transport, encoding, and protocol details required
for clients and services to communicate with each other.
Contracts
Describes how contracts define the methods of a service.
How to: Create a Service Endpoint in Configuration
Describes how to create a service endpoint in configuration.
How to: Create a Service Endpoint in Code
Describes how to create a service endpoint in code.
How to: Use Svcutil.exe to Validate Compiled Service Code
Describes how to detect errors in service implementations and configurations without hosting the
service using the ServiceModel Metadata Utility Tool (Svcutil.exe).
Endpoint Addresses
Every endpoint has an address associated with it, which is used to locate and identify the
endpoint. This address consists primarily of a Uniform Resource Identifier (URI), which
specifies the location of the endpoint. The endpoint address is represented in the Windows
Communication Foundation (WCF) programming model by the EndpointAddress class, which
contains an optional Identity property that enables the authentication of the endpoint by other
endpoints that exchange messages with it, and a set of optional Headers properties, which define
any other SOAP headers required to reach the service. The optional headers provide additional
and more detailed addressing information to identify or interact with the service endpoint. The
address of an endpoint is represented on the wire as a WS-Addressing endpoint reference (EPR).
Resource Links for 70-513 WCF Certification Exam
209
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
URI Structure of an Address
The address URI for most transports has four parts. For example, the four parts of the URI
http://www.fabrikam.com:322/mathservice.svc/secureEndpoint can be itemized as follows:
Scheme: http:
Machine: www.fabrikam.com
(optional) Port: 322
Path: /mathservice.svc/secureEndpoint
Defining an Address for a Service
The endpoint address for a service can be specified either imperatively using code or
declaratively through configuration. Defining endpoints in code is usually not practical because
the bindings and addresses for a deployed service are typically different from those used while
the service is being developed. Generally, it is more practical to define service endpoints using
configuration rather than code. Keeping the binding and addressing information out of the code
allows them to change without having to recompile or redeploy the application.
Defining an Address in Configuration
To define an endpoint in a configuration file, use the <endpoint> element element. For details
and an example, see Specifying an Endpoint Address.
Defining an Address in Code
An endpoint address can be created in code with the EndpointAddress class. For details and an
example, see Specifying an Endpoint Address.
Endpoints in WSDL
An endpoint address can also be represented in WSDL as a WS-Addressing EPR element inside
the corresponding endpoint's wsdl:port element. The EPR contains the endpoint's address as
well as any address properties. For details and an example, see Specifying an Endpoint Address.
Multiple IIS Binding Support in .NET Framework 3.5
Internet service providers often host many applications on the same server and site to increase
the site density and lower total cost of ownership. These applications are typically bound to
different base addresses. An Internet Information Services (IIS) Web site can contain multiple
applications. The applications in a site can be accessed through one or more IIS bindings.
IIS bindings provide two pieces of information: a binding protocol, and binding information. The
binding protocol defines the scheme over which communication occurs, and binding information
is the information used to access the site.
The following example shows the components that can be present in an IIS binding:
Binding protocol: HTTP
Binding Information: IP Address, Port, Host header
IIS can specify multiple bindings for each site, which results in multiple base addresses for each
scheme. Prior to .NET Framework 3.5, WCF did not support multiple addresses for a schema
and, if they were specified, threw a ArgumentException during activation.
The .NET Framework 3.5 enables Internet service providers to host multiple applications with
different base addresses for the same scheme on the same site.
For example, a site could contain the following base addresses:
http://payroll.myorg.com/Service.svc
http://shipping.myorg.com/Service.svc
Resource Links for 70-513 WCF Certification Exam
210
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
With .NET Framework 3.5, you specify a prefix filter at the AppDomain level in the
configuration file. You do this with the <baseAddressPrefixFilters> element, which contains a
list of prefixes. The incoming base addresses, supplied by IIS, are filtered based on the optional
prefix list. By default, when a prefix is not specified, all addresses are passed through.
Specifying the prefix results in only the matching base address for that scheme to be passed
through.
The following is an example of configuration code that uses the prefix filters.
<system.serviceModel>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="net.tcp://payroll.myorg.com:8000"/>
<add prefix="http://shipping.myorg.com:8000"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>
In the preceding example, net.tcp://payroll.myorg.com:8000 and http://shipping.myorg.com:9000
are the only base addresses, for their respective schemes, which are passed through.
The baseAddressPrefixFilter does not support wildcards.
The base addresses supplied by IIS may have addresses bound to other schemes not present in
baseAddressPrefixFilters list. These addresses are not filtered out.
Multiple IIS Binding Support in .NET Framework 4
Starting in .NET 4, you can enable support for multiple bindings in IIS without having to pick a
single base address, by setting ServiceHostingEnvironments MultipleSiteBindingsEnabled
setting to true. This support is limited to HTTP protocol schemes.
The following is an example of configuration code that uses multipleSiteBindingsEnabled on
<serviceHostingEnvironment>.

<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled=true >
</serviceHostingEnvironment>
</system.serviceModel>
Any baseAddressPrefixFilters settings are ignored, for both HTTP and non-HTTP protocols,
when multiple site bindings are enabled using this setting.
For details and examples, see Supporting Multiple IIS Site Bindings and
MultipleSiteBindingsEnabled.
Extending Addressing in WCF Services
The default addressing model of WCF services uses the endpoint address URI for the following
purposes:
To specify the service listening address, the location at which the endpoint listens for messages,
To specify the SOAP address filter, the address an endpoint expects as a SOAP header.
The values for each of these purposes can be specified separately, allowing several extensions of
addressing that cover useful scenarios:
SOAP intermediaries: a message sent by a client traverses one or more additional services that process
the message before it reaches its final destination. SOAP intermediaries can perform various tasks, such
as caching, routing, load-balancing, or schema validation on the messages. This scenario is accomplished
by sending messages to a separate physical address (via) that targets the intermediary rather than just
to a logical address (wsa:To) that targets the ultimate destination.
Resource Links for 70-513 WCF Certification Exam
211
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The listening address of the endpoint is a private URI and is set to a different value than its listenURI
property.
The transport address that the via specifies is the location to which a message should initially be
sent on its way to some other remote address specified by the to parameter at which the service is
located. In most Internet scenarios, the via URI is the same as the Uri property of the final to
address of the service. You only distinguish between these two addresses when you must do
manual routing.
Addressing Headers
An endpoint can be addressed by one or more SOAP headers in addition to its basic URI. One
set of scenarios where this is useful is a set of SOAP intermediary scenarios where an endpoint
requires clients of that endpoint to include SOAP headers targeted at intermediaries.
You can define custom address headers in two waysby using either code or configuration:
In code, create custom address headers by using the AddressHeader class, and then used in the
construction of an EndpointAddress.
In configuration, custom <headers> are specified as children of the <endpoint> element.
Configuration is generally preferable to code, as it allows you to change the headers after
deployment.
Custom Listening Addresses
You can set the listening address to a different value than the endpoints URI. This is useful in
intermediary scenarios where the SOAP address to be exposed is that of a public SOAP
intermediary, whereas the address where the endpoint actually listens is a private network
address.
You can specify a custom listening address by using either code or configuration:
In code, specify a custom listening address by adding a ClientViaBehavior class to the endpoints
behavior collection.
In configuration, specify a custom listening address with the ListenUri attribute of the service
<endpoint> element.
Custom SOAP Address Filter
The Uri is used in conjunction with any Headers property to define an endpoints SOAP address
filter (AddressFilter). By default, this filter verifies that an incoming message has a To message
header that matches the endpoints URI and that all of the required endpoint headers are present
in the message.
In some scenarios, an endpoint receives all messages that arrive on the underlying transport, and
not just those with the appropriate To header. To enable this, the user can use the
MatchAllMessageFilter class.
Windows Communcation Foundation
Bindings
Windows Communication Foundation (WCF) separates how the software for an application is
written from how it communicates with other software. Bindings are used to specify the
transport, encoding, and protocol details required for clients and services to communicate with
each other. WCF uses bindings to generate the underlying wire representation of the endpoint, so
most of the binding details must be agreed upon by the parties that are communicating. The
easiest way to achieve this is for clients of a service to use the same binding that the endpoint for
Resource Links for 70-513 WCF Certification Exam
212
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
the service uses. For more information about how to do this, see Using Bindings to Configure
Windows Communication Foundation Services and Clients.
A binding is made up of a collection of binding elements. Each element describes some aspect of
how the endpoint communicates with clients. A binding must include at least one transport
binding element, at least one message-encoding binding element (which the transport binding
element can provide by default), and any number of other protocol binding elements. The
process that builds a runtime out of this description allows each binding element to contribute
code to that runtime.
WCF provides bindings that contain common selections of binding elements. These can be used
with their default settings or you can modify those default values according to user requirements.
These system-provided bindings have properties that allow direct control over the binding
elements and their settings. You can also easily work side-by-side with multiple versions of a
binding by giving each version of the binding its own name. For details, see Configuring
System-Provided Bindings.
If you need a collection of binding elements not provided by one of these system-provided
bindings, you can create a custom binding that consists of the collection of binding elements
required. These custom bindings are easy to create and do not require a new class, but they do
not provide properties for controlling the binding elements or their settings. You can access the
binding elements and modify their settings through the collection that contains them. For details,
see Custom Bindings.
In This Section
Configuring System-Provided Bindings
Describes how to use and modify the bindings that WCF provides to support common scenarios.
Using Bindings to Configure Windows Communication Foundation Services and Clients
Describes how to define Windows Communication Foundation (WCF) bindings for services and clients
imperatively in code and declaratively using configuration.
Custom Bindings
Describes what a CustomBinding is and when it is used.
Contracts
This section shows you how to define and implement Windows Communication Foundation
(WCF)contracts. A service contract specifies what an endpoint communicates to the outside
world. At a more concrete level, it is a statement about a set of specific messages organized into
basic message exchange patterns (MEPs), such as request/reply, one-way, and duplex. If a
service contract is a logically related set of message exchanges, a service operation is a single
message exchange. For example, a Hello operation must obviously accept one message (so the
caller can announce the greeting) and may or may not return a message (depending upon the
courtesy of the operation).
For more information about contracts and other core WCF concepts, see Fundamental Windows
Communication Foundation Concepts. This topic focuses on understanding service contracts. For
more information about how to build clients that use service contracts to connect to services, see
WCF Client Overview. For more information about client channels, the client architecture, and
other client issues, see Clients.
Overview
Resource Links for 70-513 WCF Certification Exam
213
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
This topic provides a high-level conceptual orientation to designing and implementing WCF
services. Subtopics provide more detailed information about the specifics of designing and
implementation. Before designing and implementing your WCF application, it is recommended
that you:
Understand what a service contract is, how it works, and how to create one.
Understand that contracts state minimum requirements that run-time configuration or the hosting
environment may not support.
Service Contracts
A service contract is a statement that provides information about:
The grouping of operations in a service.
The signature of the operations in terms of messages exchanged.
The data types of these messages.
The location of the operations.
The specific protocols and serialization formats that are used to support successful communication with
the service.
For example, a purchase order contract might have a CreateOrder operation that accepts an
input of order information types and returns success or failure information, including an order
identifier. It might also have a GetOrderStatus operation that accepts an order identifier and
returns order status information. A service contract of this sort would specify:
That the purchase order contract consisted of CreateOrder and GetOrderStatus operations.
That the operations have specified input messages and output messages.
The data that these messages can carry.
Categorical statements about the communication infrastructure necessary to successfully process the
messages. For example, these details include whether and what forms of security are required to
establish successful communication.
To convey this kind of information to applications on other platforms (including non-Microsoft
platforms), XML service contracts are publicly expressed in standard XML formats, such as
Web Services Description Language (WSDL) and XML Schema (XSD), among others.
Developers for many platforms can use this public contract information to create applications
that can communicate with the service, both because they understand the language of the
specification and because those languages are designed to enable interoperation by describing the
public forms, formats, and protocols that the service supports. For more information about how
WCF handles this kind of information, see Metadata.
Contracts can be expressed many ways, however, and while WSDL and XSD are excellent
languages to describe services in an accessible way, they are difficult languages to use directly
in any case, they are merely descriptions of a service, not service contract implementations.
Therefore, WCF applications use managed attributes, interfaces, and classes both to define the
structure of and to implement a service.
The resulting contract defined in managed types can be converted (also called exported) as
metadataWSDL and XSDwhen needed by clients or other service implementers, especially
on other platforms. The result is a straightforward programming model that can be described
using public metadata to any client application. The details of the underlying SOAP messages,
such as the transportation and security-related information, can be left to WCF, which
automatically performs the necessary conversions to and from the service contract type system to
the XML type system.
Resource Links for 70-513 WCF Certification Exam
214
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
For more information about designing contracts, see Designing Service Contracts. For more
information about implementing contracts, see Implementing Service Contracts.
In addition, WCF also provides the ability to develop service contracts entirely at the message
level. For more information about developing service contracts at the message level, see Using
Message Contracts. For more information about developing services in non-SOAP XML, see
Interoperability with POX Applications.
Understanding the Hierarchy of Requirements
A service contract groups the operations; specifies the MEP, message types, and data types those
messages carry; and indicates categories of run-time behavior an implementation must have to
support the contract (for example, it may require that messages be encrypted and signed). The
service contract itself, however, does not specify precisely how these requirements are met, only
that they must be. What type of encryption or how a message is signed is up to the
implementation and configuration of a compliant service.
Notice the way that the contract requires certain things of the service contract implementation
and the run-time configuration to add behavior. The set of requirements that must be met to
expose a service for use builds on the preceding set of requirements. If a contract makes
requirements of the implementation, an implementation can require yet more of the configuration
and bindings that enable the service to run. Finally, the host application must also support any
requirements that the service configuration and bindings add.
This additive requirement process is important to keep in mind while designing, implementing,
configuring, and hosting your Windows Communication Foundation (WCF) service application.
For example, the contract can specify that it needs to support a session. If so, then you must
configure the binding to support that contractual requirement, or the service implementation will
not work. Or if your service requires Integrated Windows authentication and is hosted in Internet
Information Services (IIS), the Web application in which the service resides must have
Integrated Windows authentication turned on and anonymous support turned off. For more
information about the features and impact of the different service host application types, see
Hosting.
How to: Create a Service Endpoint in
Configuration
Endpoints provide clients with access to the functionality a Windows Communication
Foundation (WCF) service offers. You can define one or more endpoints for a service by using a
combination of relative and absolute endpoint addresses, or if you do not define any service
endpoints, the runtime provides some by default for you. This topic shows how to add endpoints
using a configuration file that contain both relative and absolute addresses.
Example
The following service configuration specifies a base address and five endpoints.
XML
<configuration>
<appSettings>
<!-- use appSetting to configure base address provided by host -->
<addkey="baseAddress"
value="http://localhost:8000/servicemodelsamples/service" />
</appSettings>
Resource Links for 70-513 WCF Certification Exam
215
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<system.serviceModel>
<services>
<!-- This section is optional with the default configuration introduced
in .NET Framework 4. -->
<servicename="Microsoft.ServiceModel.Samples.CalculatorService">
<host>
<baseAddresses>
<addbaseAddress="http://localhost:8000/ServiceModelSamples/service"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpointaddress="/test" binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpointaddress="http://localhost:8001/hello/servicemodelsamples"
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<endpointaddress="net.tcp://localhost:9000/servicemodelsamples/service"
binding="netTcpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<!-- the mex endpoint is another relative address exposed at
http://localhost:8000/ServiceModelSamples/service/mex -->
<endpointaddress="mex"binding="mexHttpBinding"contract="IMetadataExchange" />
</service>
</services>
<!--For debugging purposes set the includeExceptionDetailInFaults attribute
to true-->
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadatahttpGetEnabled="True"/>
<serviceDebugincludeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

The base address is specified using the add element, under service/host/baseAddresses, as shown
in the following sample.
XML
<service
name="Microsoft.ServiceModel.Samples.CalculatorService">
<host>
<baseAddresses>
<addbaseAddress="http://localhost:8000/ServiceModelSamples/service"/>
</baseAddresses>
</host>
The first endpoint definition shown in the following sample specifies a relative address, which
means the endpoint address is a combination of the base address and the relative address
following the rules of Uniform Resource Identifier (URI) composition. The relative address is
empty (""), so the endpoint address is the same as the base address. The actual endpoint address
is http://localhost:8000/servicemodelsamples/service.
None
Resource Links for 70-513 WCF Certification Exam
216
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<endpoint address="" binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />

The second endpoint definition also specifies a relative address, as shown in the following
sample configuration. The relative address, "test", is appended to the base address. The actual
endpoint address is http://localhost:8000/servicemodelsamples/service/test.
None
<endpoint address="/test"binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />

The third endpoint definition specifies an absolute address, as shown in the following sample
configuration. The base address plays no role in the address. The actual endpoint address is
http://localhost:8001/hello/servicemodelsamples.
None
<endpoint address="http://localhost:8001/hello/servicemodelsamples"
binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />

The fourth endpoint address specifies an absolute address and a different transportTCP. The
base address plays no role in the address. The actual endpoint address is
net.tcp://localhost:9000/servicemodelsamples/service.
To use the default endpoints provided by the runtime, do not specify any service endpoints in
either the code or the configuration file. In this example, the runtime creates the default
endpoints when the service is opened. For more information about default endpoints, bindings,
and behaviors, see Simplified Configuration and Simplified Configuration for WCF Services.
XML
<configuration>
<appSettings>
<!-- use appSetting to configure base address provided by host -->
<addkey="baseAddress"
value="http://localhost:8000/servicemodelsamples/service" />
</appSettings>
<system.serviceModel>
<!--For debugging purposes set the includeExceptionDetailInFaults attribute
to true-->
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadatahttpGetEnabled="True"/>
<serviceDebugincludeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
How to: Create a Service Endpoint in Code
In this example, an ICalculator contract is defined for a calculator service, the service is
implemented in the CalculatorService class, and then its endpoint is defined in code, where it
is specified that the service must use the BasicHttpBinding class.
Resource Links for 70-513 WCF Certification Exam
217
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
It is usually the best practice to specify the binding and address information declaratively in
configuration rather than imperatively in code. Defining endpoints in code is usually not
practical because the bindings and addresses for a deployed service are typically different from
those used while the service is being developed. More generally, keeping the binding and
addressing information out of the code allows them to change without having to recompile or
redeploy the application.
To create a service endpoint in code
1. Create the interface that defines the service contract.
C#
[ServiceContract]
publicinterface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
2. Implement the service contract defined in step 1.
C#
publicclass CalculatorService : ICalculator
{
publicdouble Add(double n1, double n2)
{
return n1 + n2;
}
publicdouble Subtract(double n1, double n2)
{
return n1 - n2;
}
publicdouble Multiply(double n1, double n2)
{
return n1 * n2;
}
publicdouble Divide(double n1, double n2)
{
return n1 / n2;
}
}

3. In the hosting application, create the base address for the service and the binding to be used with
the service.
C#
// Specify a base address for the service
String baseAddress = "http://localhost/CalculatorService";
// Create the binding to be used by the service.
BasicHttpBinding binding1 = new BasicHttpBinding();
Resource Links for 70-513 WCF Certification Exam
218
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
4. Create the host and call AddServiceEndpoint or one of the other overloads to add the service
endpoint for the host.
C#
using(ServiceHost host = new ServiceHost(typeof(CalculatorService)))
{
host.AddServiceEndpoint(typeof(ICalculator),binding1, baseAddress);

To specify the binding in code, but to use the default endpoints provided by the runtime, pass the
bass address into constructor when creating the ServiceHost, and do not call
AddServiceEndpoint.
C#
ServiceHost host = new ServiceHost(typeof(CalculatorService), new
Uri(baseAddress));
For more information about default endpoints, see Simplified Configuration and Simplified
Configuration for WCF Services.
How to: Use Svcutil.exe to Validate Compiled
Service Code
You can use the ServiceModel Metadata Utility Tool (Svcutil.exe) to detect errors in service
implementations and configurations without hosting the service.
To validate a service
1. Compile your service into an executable file and one or more dependent assemblies.
2. Open an SDK command prompt
3. At the command prompt, launch the Svcutil.exe tool using the following format. For more
information on the various parameters, see the Service Validationsection of the ServiceModel
Metadata Utility Tool (Svcutil.exe) topic.
4. svcutil.exe /validate /serviceName:<serviceConfigName><assemblyPath>*
You must use the /serviceName option to indicate the configuration name of the service you
want to validate.
The assemblyPath argument specifies the path to the executable file for the service and one or
more assemblies that contain the service types to be validated. The executable assembly must
have an associated configuration file to provide the service configuration. You can use standard
command-line wildcards to provide multiple assemblies.
Example
The following command the service myServiceName implemented in the myServiceHost.exe
executable file. The configuration file for the service (myServiceHost.exe.config) is
automatically loaded.
svcutil /validate /serviceName:myServiceName myServiceHost.exe
Standard Endpoints
Endpoints are defined by specifying an address, a binding, and a contract. Other parameters that
may be set on an endpoint include behavior configuration, headers, and listen URIs. For certain
types of endpoints these values do not change. For example, metadata exchange endpoints
always use the IMetadataExchange contract. Other endpoints, such as WebHttpEndpoint always
require a specified endpoint behavior. The usability of an endpoint can be improved by having
Resource Links for 70-513 WCF Certification Exam
219
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
endpoints with default values for commonly used endpoint properties. Standard endpoints enable
a developer to define an endpoint that has default values or where one or more endpoints
properties does not change. These endpoints allow you to use such an endpoint without having to
specify information of a static nature. Standard endpoints can be used for infrastructure and
application endpoints.
Infrastructure Endpoints
A service may expose endpoints with some of the properties not explicitly implemented by the
service author. For example, the metadata exchange endpoint exposes the IMetadataExchange
contract but as a service author you do not implement that interface, it is implemented by WCF.
Such infrastructure endpoints have default values for one or more endpoint properties, some of
which may be unalterable. The Contract property of the metadata exchange endpoint must be
IMetadataExchange, while other properties like binding can be supplied by the developer.
Infrastructure endpoints are identified by setting the IsSystemEndpoint property to true.
Application Endpoints
Application developers can define their own standard endpoints which specify default values for
the address, binding, or contract. You define a standard endpoint by deriving a class from
ServiceEndpoint and setting the appropriate endpoint properties. You can provide default values
for properties that can be changed. Some other properties will have static values that cannot
change. The following example shows how to implement a standard endpoint.
public class CustomEndpoint : ServiceEndpoint
{
public CustomEndpoint(): this(string.Empty){}
public CustomEndpoint(string address): this(address,
ContractDescription.GetContract(typeof(ICalculator))) {}
// Create the custom endpoint with a fixed binding
public CustomEndpoint(string address, ContractDescription contract)
: base(contract)
{
this.Binding = new BasicHttpBinding();
this.IsSystemEndpoint = false;
}
// Definition of the additional property of this endpoint
public bool Property
{ get; set; }
}
To use a user-defined custom endpoint in a configuration file you must derive a class from
StandardEndpointElement, derive a class from StandardEndpointCollectionElement, and register
the new standard endpoint in the extensions section in app.config or machine.config. The
StandardEndpointElement provides configuration support for the standard endpoint, as shown
in the following example.
public class CustomEndpointElement : StandardEndpointElement
{
// Definition of the additional property for the standard endpoint element
public bool Property
{
get { return (bool)base["property"]; }
set { base["property"] = value; }
}
Resource Links for 70-513 WCF Certification Exam
220
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
// The additional property needs to be added to the properties of the
standard endpoint element
protected override ConfigurationPropertyCollection Properties
{
get{
ConfigurationPropertyCollection properties = base.Properties;
properties.Add(new ConfigurationProperty("property", typeof(bool), false,
ConfigurationPropertyOptions.None));
return properties;
}
}
// Return the type of this standard endpoint
protected override Type EndpointType
{
get { return typeof(CustomEndpoint); }
}
// Create the custom service endpoint
protected override ServiceEndpoint CreateServiceEndpoint(ContractDescription
contract)
{
return new CustomEndpoint();
}
// Read the value given to the property in config and save it
protected override void OnApplyConfiguration(ServiceEndpoint endpoint,
ServiceEndpointElement serviceEndpointElement)
{
CustomEndpoint customEndpoint = (CustomEndpoint)endpoint;
customEndpoint.Property = this.Property;
}
// Read the value given to the property in config and save it
protected override void OnApplyConfiguration(ServiceEndpoint endpoint,
ChannelEndpointElement channelEndpointElement)
{
CustomEndpoint customEndpoint = (CustomEndpoint)endpoint;
customEndpoint.Property = this.Property;
}
// No validation in this sample
protected override void OnInitializeAndValidate(ServiceEndpointElement
serviceEndpointElement) { }
// No validation in this sample
protected override void OnInitializeAndValidate(ChannelEndpointElement
channelEndpointElement) {}
}
The StandardEndpointCollectionElement provides the backing type for the collection that
appears under the <standardEndpoints> section in the configuration for the standard endpoint.
The following example shows how to implement this class.
public class CustomEndpointCollectionElement :
StandardEndpointCollectionElement<CustomEndpoint, CustomEndpointElement>
{
// ...
}
The following example shows how to register a standard endpoint in the extensions section.
<extensions>
<standardEndpointExtensions>
Resource Links for 70-513 WCF Certification Exam
221
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<add name="customStandardEndpoint"type="CustomEndpointCollectionElement,
Example.dll, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=ffffffffffffffff"/>
Configuring a Standard Endpoint
Standard endpoints can be added in code or in configuration. To add a standard endpoint in code
simply instantiate the appropriate standard endpoint type and add it to the service host as shown
in the following example:
C#
serviceHost.AddServiceEndpoint(new CustomEndpoint());
To add a standard endpoint in configuration, add an <endpoint> element to the <service>
element and any needed configuration settings in the <standardEndpoints> element. The
following example shows how to add a UdpDiscoveryEndpoint, one of the standard endpoints
that ships with .NET Framework 4.
XML
<services>
<service>
<endpoint isSystemEndpoint=true kind=udpDiscoveryEndpoint />
</service>
</services>
<standardEndpoints>
<udpDiscoveryEndpoint>
<standardEndpointmulticastAddress="soap.udp://239.255.255.250:3702" />
</udpDiscoveryEndpoint>
</ standardEndpoints >
The type of standard endpoint is specified using the kind attribute in the <endpoint> element.
The endpoint is configured within the <standardEndpoints> element. In the example above, a
UdpDiscoveryEndpoint endpoint is added and configured. The <udpDiscoveryEndpoint>
element contains a <standardEndpoint> that sets the MulticastAddress property of the
UdpDiscoveryEndpoint.
Standard Endpoints Shipped with the .NET Framework
The following table lists the standard endpoints shipped with .NET Framework 4.
Mex Endpoint
A standard endpoint that is used to expose service metadata.
AnnouncementEndpoint
A standard endpoint that is used by services to send announcement messages.
DiscoveryEndpoint
A standard endpoint that is used by services to send discovery messages.
UdpDiscoveryEndpoint
A standard endpoint that is pre-configured for discovery operations over a UDP multicast binding.
UdpAnnouncementEndpoint
A standard endpoint that is used by services to send announcement messages over a UDP binding.
DynamicEndpoint
A standard endpoint that uses WS-Discovery to find the endpoint address dynamically at runtime.
ServiceMetadataEndpoint
A standard endpoint for metadata exchange.
Resource Links for 70-513 WCF Certification Exam
222
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
WebHttpEndpoint
A standard endpoint with a WebHttpBinding binding that automatically adds the WebHttpBehavior
behavior
WebScriptEndpoint
A standard endpoint with a WebHttpBinding binding that automatically adds the
WebScriptEnablingBehavior behavior.
WebServiceEndpoint
A standard endpoint with a WebHttpBinding binding.
WorkflowControlEndpoint
A standard endpoint that enables you to call control operations on workflow instances.
WorkflowHostingEndpoint
A standard endpoint that supports workflow creation and bookmark resumption.

Configure Behaviors.This objective may include but is not limited to: applying service, endpoint,
and operation behaviors in configuration and codeThis objective does not include: creating a
custom behavior; creating and using dispatch behaviors,loading configuration from a location
other than the default application configuration file
Configuring and Extending the Runtime with
Behaviors
Behaviors enable you to modify default behavior and add custom extensions that inspect and
validate service configuration or modify runtime behavior in Windows Communication
Foundation (WCF) client and service applications. This topic describes the behavior interfaces,
how to implement them, and how to add them to the service description (in a service application)
or endpoint (in a client application) programmatically or in a configuration file. For more
information about using system-provided behaviors, see Specifying Service Run-Time Behavior
and Specifying Client Run-Time Behavior.
Behaviors
Behavior types are added to the service or service endpoint description objects (on the service or
client, respectively) before those objects are used by Windows Communication Foundation
(WCF) to create a runtime that executes a WCF service or a WCF client. When these behaviors
are called during the runtime construction process they are then able to access runtime properties
and methods that modify the runtime constructed by the contract, bindings, and addresses.
Behavior Methods
All behaviors have an AddBindingParameters method, an ApplyDispatchBehavior method, a
Validate method, and an ApplyClientBehavior method with one exception: Because
IServiceBehavior cannot execute in a client, it does not implement ApplyClientBehavior.
Use the AddBindingParameters method to modify or add custom objects to a collection that
custom bindings can access for their use when the runtime is constructed. For example, this how
protection requirements are specified that affect the way the channel is built, but are not known
by the channel developer.
Use the Validate method to examine the description tree and corresponding runtime object to
ensure it conforms to some set of criteria.
Resource Links for 70-513 WCF Certification Exam
223
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Use the ApplyDispatchBehavior and ApplyClientBehavior methods to examine the description
tree and modify the runtime for a particular scope on either the service or the client. You can also
insert extension objects as well.
Note
Although a description tree is provided in these methods, it is for examination only. If a description
tree is modified, the behavior is undefined.
The properties you can modify and the customization interfaces you can implement are accessed
through the service and client runtime classes. The service types are the DispatchRuntime and
DispatchOperation classes. The client types are the ClientRuntime and ClientOperation classes.
The ClientRuntime and DispatchRuntime classes are the extensibility entry points to access
client-wide and service-wide runtime properties and extension collections, respectively.
Similarly, the ClientOperation and DispatchOperation classes expose client operation and service
operation runtime properties and extension collections, respectively. You can, however, access
the wider scoped runtime object from the operation runtime object and vice versa if need be.
Note
For a discussion of runtime properties and extension types that you can use to modify the
execution behavior of a client, see Extending Clients. For a discussion of runtime properties and
extension types that you can use to modify the execution behavior of a service dispatcher, see
Extending Dispatchers.
Most WCF users do not interact with the runtime directly; instead they use core programming
model constructs like endpoints, contracts, bindings, addresses, and behavior attributes on
classes or behaviors in configuration files. These constructs make up the description tree, which
is the complete specification for constructing a runtime to support a service or client described
by the description tree.
There are four kinds of behaviors in WCF:
Service behaviors (IServiceBehavior types) enable the customization of the entire service
runtime including ServiceHostBase.
Endpoint behaviors (IEndpointBehavior types) enable the customization of service endpoints and
their associated EndpointDispatcher objects.
Contract behaviors (IContractBehavior types) enable the customization of both the
ClientRuntime and DispatchRuntime classes in client and service applications, respectively.
Operation behaviors (IOperationBehavior types) enable the customization of the ClientOperation
and DispatchOperation classes, again, on the client and service.
You can add these behaviors to the various description objects by implementing custom
attributes, using application configuration files, or directly by adding them to the behaviors
collection on the appropriate description object. The must, however, be added to a service
description or service endpoint description object prior to calling ICommunicationObject.Open
on the ServiceHost or a ChannelFactory<TChannel>.
Behavior Scopes
There are four behavior types, each of which corresponds to a particular scope of runtime access.
Service Behaviors
Service behaviors, which implement IServiceBehavior, are the primary mechanism by which you
modify the entire service runtime. There are three mechanisms for adding service behaviors to a
service.
Resource Links for 70-513 WCF Certification Exam
224
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
1. Using an attribute on the service class. When a ServiceHost is constructed, the ServiceHost
implementation uses reflection to discover the set of attributes on the type of the service. If any
of those attributes are implementations of IServiceBehavior, they are added to the behaviors
collection on ServiceDescription. This allows those behaviors to participate in the construction
of the service run time.
2. Programmatically adding the behavior to the behaviors collection on ServiceDescription. This
can be accomplished with the following lines of code:
3. ServiceHost host = new ServiceHost(/* Parameters */);
4. host.Description.Behaviors.Add(/* Service Behavior */);
5. Implementing a custom BehaviorExtensionElement that extends configuration. This enables the
use of the service behavior from application configuration files.
Examples of service behaviors in WCF include the ServiceBehaviorAttribute attribute, the
ServiceThrottlingBehavior, and the ServiceMetadataBehavior behavior.
Contract Behaviors
Contract behaviors, which implement the IContractBehavior interface, are used to extend both
the client and service runtime across a contract.
There are two mechanisms for adding contract behaviors to a contract. The first mechanism is to
create a custom attribute to be used on the contract interface. When a contract interface is passed
to either a ServiceHost or a ChannelFactory<TChannel>, WCF examines the attributes on the
interface. If any attributes are implementations of IContractBehavior, those are added to the
behaviors collection on the System.ServiceModel.Description.ContractDescription created for
that interface.
You can also implement the System.ServiceModel.Description.IContractBehaviorAttribute on
the custom contract behavior attribute. In this case, the behavior is as follows when applied to:
A contract interface. In this case, the behavior is applied to all contracts of that type in any
endpoint and WCF ignores the value of the IContractBehaviorAttribute.TargetContract property.
A service class. In this case, the behavior is applied only to endpoints the contract of which is
the value of the TargetContract property.
A callback class. In this case, the behavior is applied to the duplex client's endpoint and WCF
ignores the value of the TargetContract property.
The second mechanism is to add the behavior to the behaviors collection on a
ContractDescription.
Examples of contract behaviors in WCF include the
System.ServiceModel.DeliveryRequirementsAttribute attribute. For more information and an
example, see the reference topic.
Endpoint Behaviors
Endpoint behaviors, which implement IEndpointBehavior, are the primary mechanism by which
you modify the entire service or client run time for a specific endpoint.
There are two mechanisms for adding endpoint behaviors to a service.
1. Add the behavior to the Behaviors property.
2. Implement a custom BehaviorExtensionElement that extends configuration.
For more information and an example, see the reference topic.
Operation Behaviors
Operation behaviors, which implement the IOperationBehavior interface, are used to extend both
the client and service runtime for each operation.
Resource Links for 70-513 WCF Certification Exam
225
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
There are two mechanisms for adding operation behaviors to an operation. The first mechanism
is to create a custom attribute to be used on the method that models the operation. When an
operation is added to either a ServiceHost or a ChannelFactory, WCF adds any
IOperationBehavior attributes to the behaviors collection on the OperationDescription created for
that operation.
The second mechanism is by directly adding the behavior to the behaviors collection on a
constructed OperationDescription.
Examples of operation behaviors in WCF include the OperationBehaviorAttribute and the
TransactionFlowAttribute.
For more information and an example, see the reference topic.
Using Configuration to Create Behaviors
Service and endpoint, and contract behaviors can by designed to be specified in code or using
attributes; only service and endpoint behaviors can be configured using application or Web
configuration files. Exposing behaviors using attributes allows developers to specify a behavior
at compilation-time that cannot be added, removed, or modified at runtime. This is often suitable
for behaviors that are always required for the correct operation of a service (for example, the
transaction-related parameters to the System.ServiceModel.ServiceBehaviorAttribute attribute).
Exposing behaviors using configuration allows developers to leave the specification and
configuration of those behaviors to those who deploy the service. This is suitable for behaviors
that are optional components or other deployment-specific configuration, such as whether
metadata is exposed for the service or the particular authorization configuration for a service.
Note
You can also use behaviors that support configuration to enforce company application policies
by inserting them into the machine.config configuration file and locking those items down. For a
description and an example, see How to: Lock Down Endpoints in the Enterprise.
To expose a behavior using configuration, a developer must create a derived class of
BehaviorExtensionElement and then register that extension with configuration.
The following code example shows how an IEndpointBehavior implements
BehaviorExtensionElement:
// BehaviorExtensionElement members
public override Type BehaviorType
{
get { return typeof(EndpointBehaviorMessageInspector); }
}
protected override object CreateBehavior()
{
return new EndpointBehaviorMessageInspector();
}
In order for the configuration system to load a custom BehaviorExtensionElement, it must be
registered as an extension. The following code example shows the configuration file for the
preceding endpoint behavior:
Xml
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.WCF.Documentation.SampleService"
behaviorConfiguration="metadataSupport" >
Resource Links for 70-513 WCF Certification Exam
226
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/ServiceMetadata" />
</baseAddresses>
</host>
<endpointaddress="/SampleService" binding="wsHttpBinding"
behaviorConfiguration="withMessageInspector"
contract="Microsoft.WCF.Documentation.ISampleService" />
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metadataSupport">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="withMessageInspector">
<endpointMessageInspector />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="endpointMessageInspector"
type="Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector,
HostApplication, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
/></behaviorExtensions>
</extensions>
</system.serviceModel>
</configuration>
Where Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector is the behavior
extension type and HostApplication is the name of the assembly into which that class has been
compiled.
Evaluation Order
The System.ServiceModel.ChannelFactory<TChannel> and the
System.ServiceModel.ServiceHost are responsible for building the runtime from the
programming model and description. Behaviors, as previously described, contribute to that build
process at the service, endpoint, contract, and operation.
The ServiceHost applies behaviors in the following order:
1. Service
2. Contract
3. Endpoint
4. Operation
Within any collection of behaviors, no order is guaranteed.
The ChannelFactory<TChannel> applies behaviors in the following order:
1. Contract
2. Endpoint
3. Operation
Resource Links for 70-513 WCF Certification Exam
227
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Within any collection of behaviors, again, no order is guaranteed.
Adding Behaviors Programmatically
Properties of the System.ServiceModel.Description.ServiceDescription in the service application
must not be modified subsequent to the CommunicationObject.OnOpening method on
System.ServiceModel.ServiceHostBase. Some members, like the ServiceHostBase.Credentials
property and the AddServiceEndpoint methods on ServiceHostBase and
System.ServiceModel.ServiceHost, throw an exception if modified past that point. Others permit
you to modify them, but the result is undefined.Similarly, on the client the
System.ServiceModel.Description.ServiceEndpoint values must not be modified after the call to
OnOpening on the System.ServiceModel.ChannelFactory. The ChannelFactory.Credentials
property throws an exception if modified past that point, but the other client description values
can be modified without error. The result, however, is undefined. Whether for the service or
client, it is recommended that you modify the description prior to calling
CommunicationObject.Open.
Inheritance Rules for Behavior Attributes
All four types of behaviors can be populated using attributes service behaviors and contract
behaviors. Because attributes are defined on managed objects and members, and managed
objects and members support inheritance, it is necessary to define how behavior attributes work
in the context of inheritance.At a high level, the rule is that for a particular scope (for example,
service, contract, or operation), all behavior attributes in the inheritance hierarchy for that scope
are applied. If there are two behavior attributes of the same type, only the most-derived type is
used.
Service Behaviors
For a given service class, all service behavior attributes on that class, and on parents of that class,
are applied. If the same type of attribute is applied at multiple places in the inheritance hierarchy,
the most-derived type is used.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirementsAttribute(
AspNetCompatibilityRequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class A { /* */ }
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class B : A { /* */}
For example, in the preceding case, the service B ends up with an InstanceContextMode of
Single, an AspNetCompatibilityRequirementsMode mode of Allowed, and a ConcurrencyMode
of Single. The ConcurrencyMode is Single, because ServiceBehaviorAttribute attribute on
service B is on "more derived" than that on service A.
Contract Behaviors
For a given contract, all contract behavior attributes on that interface and on parents of that
interface, are applied. If the same type of attribute is applied at multiple places in the inheritance
hierarchy, the most-derived type is used.
Operation Behaviors
If a given operation does not override an existing abstract or virtual operation, no inheritance
rules apply.If an operation does override an existing operation, then all operation behavior
attributes on that operation and on parents of that operation, are applied. If the same type of
attribute is applied at multiple places in the inheritance hierarchy, the most-derived type is used.
Resource Links for 70-513 WCF Certification Exam
228
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Implement self hosting.This objective may include but is not limited to: configuring and
instantiating a service hostThis objective does not include: implementing a custom service host
How to: Host a WCF Service in a Managed
Application
To host a service inside a managed application, embed the code for the service inside the
managed application code, define an endpoint for the service either imperatively in code,
declaratively through configuration, or using default endpoints, and then create an instance of
ServiceHost. To start receiving messages, call Open on ServiceHost. This creates and opens the
listener for the service. Hosting a service in this way is often referred to as "self-hosting" because
the managed application is doing the hosting work itself. To close the service, call
System.ServiceModel.Channels.CommunicationObject.Close on ServiceHost.
A service can also be hosted in a managed Windows service, in Internet Information Services
(IIS), or in Windows Process Activation Service (WAS). For more information about hosting
options for a service, see Hosting Services.Hosting a service in a managed application is the
most flexible option because it requires the least infrastructure to deploy. For more information
about hosting services in managed applications, see Hosting in a Managed Application.
The following procedure demonstrates how to implement a self-hosted service in a console
application.
To create a self-hosted service
1. Open Visual Studio 2010 and select New, Project... from the File menu.
2. In the Installed Templates list, select Visual C#, Windows or Visual Basic, Windows.
Depending on your Visual Studio 2010 settings, one or both of these may be under the Other
Languages node in the Installed Templates list.
3. Select Console Application from the Windows list. Type SelfHost in the Name box and click
OK.
4. Right-click SelfHost in Solution Explorer and select Add Reference.... Select
System.ServiceModel from the .NET tab and click OK.
Tip:
If the Solution Explorer window is not visible, select Solution Explorer from the View menu.
5. Double-click Program.cs or Module1.vb in Solution Explorer to open it in the code window if
it is not already open. Add the following statements at the top of the file.
C#
using System.ServiceModel;
using System.ServiceModel.Description;
6. Define and implement a service contract. This example defines a HelloWorldService that
returns a message based on the input to the service.
C#
[ServiceContract]
publicinterface IHelloWorldService
{
[OperationContract]
string SayHello(string name);
}

Resource Links for 70-513 WCF Certification Exam
229
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
publicclass HelloWorldService : IHelloWorldService
{
publicstring SayHello(string name)
{
returnstring.Format("Hello, {0}", name);
}
}

Note:
For more information about how to define and implement a service interface, see How to: Define a
Windows Communication Foundation Service Contract and How to: Implement a Windows
Communication Foundation Service Contract.
7. At the top of the Main method, create an instance of the Uri class with the base address for the
service.
C#
Uri baseAddress = new Uri("http://localhost:8080/hello");

8. Create an instance of the ServiceHost class, passing a Type that represents the service type and
the base address Uniform Resource Identifier (URI) to the ServiceHost. Enable metadata
publishing, and then call the Open method on the ServiceHost to initialize the service and
prepare it to receive messages.
C#
// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(HelloWorldService),
baseAddress))
{
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// Open the ServiceHost to start listening for messages. Since
// no endpoints are explicitly configured, the runtime will create
// one endpoint per base address for each service contract implemented
// by the service.
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
Note:
This example uses default endpoints, and no configuration file is required for this service. If no
endpoints are configured, then the runtime creates one endpoint for each base address for each
service contract implemented by the service. For more information about default endpoints, see
Simplified Configuration and Simplified Configuration for WCF Services.
9. Press CTRL+SHIFT+B to build the solution.
To test the service
Resource Links for 70-513 WCF Certification Exam
230
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
1. Press Ctrl + F5 to run the service.
2. Open WCF Test Client.
Tip:
To open WCF Test Client, open a Visual Studio 2010 command prompt and execute
WcfTestClient.exe.
3. Select Add Service... from the File menu.
4. Type http://localhost:8080/hello into the address box and click OK.
Tip:
Make sure the service is running or else this step fails. If you have changed the base address in the
code, then use the modified base address in this step.
5. Double-click SayHello under the My Service Projects node. Type your name into the Value
column in the Request list, and click Invoke. A reply message appears in the Response list.
Example
The following example creates a ServiceHost object to host a service of type
HelloWorldService, and then calls the Open method on ServiceHost. A base address is
provided in code, metadata publishing is enabled, and default endpoints are used.
C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace SelfHost
{
[ServiceContract]
publicinterface IHelloWorldService
{
[OperationContract]
string SayHello(string name);
}
publicclass HelloWorldService : IHelloWorldService
{
publicstring SayHello(string name)
{
returnstring.Format("Hello, {0}", name);
}
}
class Program
{
staticvoid Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:8080/hello");

// Create the ServiceHost.
using (ServiceHost host = new ServiceHost(typeof(HelloWorldService),
baseAddress))
{
// Enable metadata publishing.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
Resource Links for 70-513 WCF Certification Exam
231
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
// Open the ServiceHost to start listening for messages. Since
// no endpoints are explicitly configured, the runtime will create
// one endpoint per base address for each service contract implemented
// by the service.
host.Open();
Console.WriteLine("The service is ready at {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service.");
Console.ReadLine();
// Close the ServiceHost.
host.Close();
}
}
}
}
Implement Web server hosting.This objective may include but is not limited to: configuring
IIS/WAS for WCF; deploying to IIS/WAS; file-less configuration; specifying a ServiceHostThis
objective does not include: Windows Application Server
How to: Host a WCF Service in IIS
This topic outlines the basic steps required to create a Windows Communication Foundation
(WCF) service that is hosted in Internet Information Services (IIS). This topic assumes you are
familiar with IIS and understand how to use the IIS management tool to create and manage IIS
applications. For more information about IIS see Internet Information Services A WCF service
that runs in the IIS environment takes full advantage of IIS features, such as process recycling,
idle shutdown, process health monitoring, and message-based activation. This hosting option
requires that IIS be properly configured, but it does not require that any hosting code be written
as part of the application. You can use IIS hosting only with an HTTP transport.
For more information about how WCF and ASP.NET interact, see WCF Services and ASP.NET.
For more information about configuring security, see Windows Communication Foundation
Security.For the source copy of this example, see IIS Hosting Using Inline Code.
To create a service hosted by IIS
Confirm that IIS is installed and running on your computer. For more information about
installing and configuring IIS see Installing and Configuring IIS 7.0
Create a new folder for your application files called "IISHostedCalcService", ensure that
ASP.NET has access to the contents of the folder, and use the IIS management tool to create a
new IIS application that is physically located in this application directory. When creating an alias
for the application directory use "IISHostedCalc".
Create a new file named "service.svc" in the application directory. Edit this file by adding the
following @ServiceHost element.
<%@ServiceHost language=c# Debug="true"
Service="Microsoft.ServiceModel.Samples.CalculatorService"%>
Create an App_Code subdirectory within the application directory.
Create a code file named Service.cs in the App_Code subdirectory.
Add the following using statements to the top of the Service.cs file.
using System;
using System.ServiceModel;
Resource Links for 70-513 WCF Certification Exam
232
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Add the following namespace declaration after the using statements.
namespace Microsoft.ServiceModel.Samples
{
}
Define the service contract inside the namespace declaration as shown in the following code.
C#
[ServiceContract]
publicinterface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
Implement the service contract after the service contract definition as shown in the following code.
C#
publicclass CalculatorService : ICalculator
{
publicdouble Add(double n1, double n2)
{
return n1 + n2;
}
publicdouble Subtract(double n1, double n2)
{
return n1 - n2;
}
publicdouble Multiply(double n1, double n2)
{
return n1 * n2;
}
publicdouble Divide(double n1, double n2)
{
return n1 / n2;
}
}


1. Create a file named "Web.config" in the application directory and add the following
configuration code into the file. At runtime, the WCF infrastructure uses the information to
construct an endpoint that client applications can communicate with.
XML
<?xmlversion="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<!-- This section is optional with the default configuration
model introduced in .NET Framework 4 -->
<servicename="Microsoft.ServiceModel.Samples.CalculatorService">
<!-- This endpoint is exposed at the base address provided by host:
http://localhost/servicemodelsamples/service.svc -->
Resource Links for 70-513 WCF Certification Exam
233
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<endpoint address="" binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<!-- The mex endpoint is exposed at
http://localhost/servicemodelsamples/service.svc/mex -->
<endpointaddress="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
This example explicitly specifies endpoints in the configuration file. If you do not add any
endpoints to the service, the runtime adds default endpoints for you. For more information about
default endpoints, bindings, and behaviors see Simplified Configuration and Simplified
Configuration for WCF Services.
2. To make sure the service is hosted correctly, open an instance of Internet Explorer and browse to
the service's URL: http://localhost/IISHostedCalc/Service.svc
Example
The following is a complete listing of the code for the IIS hosted calculator service.
C#
using System;
using System.ServiceModel;
namespace Microsoft.ServiceModel.Samples
{
[ServiceContract]
publicinterface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
publicclass CalculatorService : ICalculator
{
publicdouble Add(double n1, double n2)
{
return n1 + n2;
}
publicdouble Subtract(double n1, double n2)
{
return n1 - n2;
}
publicdouble Multiply(double n1, double n2)
{
return n1 * n2;
}
publicdouble Divide(double n1, double n2)
{
return n1 / n2;
}
Resource Links for 70-513 WCF Certification Exam
234
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
}
C#
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.CalculatorService">
<!-- This endpoint is exposed at the base address provided by host:
http://localhost/servicemodelsamples/service.svc -->
<endpoint address="" binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<!-- The mex endpoint is explosed at
http://localhost/servicemodelsamples/service.svc/mex -->
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
None
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="Microsoft.ServiceModel.Samples.CalculatorService">
<!-- This endpoint is exposed at the base address provided by host:
http://localhost/servicemodelsamples/service.svc -->
<endpoint address="" binding="wsHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculator" />
<!-- The mex endpoint is explosed at
http://localhost/servicemodelsamples/service.svc/mex -->
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
How to: Host a WCF Service in WAS
This topic outlines the basic steps required to create a Windows Process Activation Services
(also known as WAS) hosted Windows Communication Foundation (WCF) service. WAS is the
new process activation service that is a generalization of Internet Information Services (IIS)
features that work with non-HTTP transport protocols. WCF uses the listener adapter interface to
communicate activation requests that are received over the non-HTTP protocols supported by
WCF, such as TCP, named pipes, and Message Queuing. This hosting option requires that WAS
activation components are properly installed and configured, but it does not require any hosting
code to be written as part of the application. For more information about installing and
configuring WAS, see How to: Install and Configure WCF Activation Components.
Caution:
WAS activation is not supported if the web servers request processing pipeline is set to Classic
mode. The web servers request processing pipeline must be set to Integrated mode if WAS
Resource Links for 70-513 WCF Certification Exam
235
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
activation is to be used.
When a WCF service is hosted in WAS, the standard bindings are used in the usual way.
However, when using the NetTcpBinding and the NetNamedPipeBinding to configure a WAS-
hosted service, a constraint must be satisfied. When different endpoints use the same transport,
the binding settings have to match on the following seven properties:
ConnectionBufferSize
ChannelInitializationTimeout
MaxPendingConnections
MaxOutputDelay
MaxPendingAccepts
ConnectionPoolSettings.IdleTimeout
ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint
Otherwise, the endpoint that is initialized first always determines the values of these properties,
and endpoints added later throw a ServiceActivationException if they do not match those
settings.For the source copy of this example, see TCP Activation.
To create a basic service hosted by WAS
1. Define a service contract for the type of service.
C#
[ServiceContract]
publicinterface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}

2. Implement the service contract in a service class. Note that address or binding information is not
specified inside the implementation of the service. Also, code does not have to be written to
retrieve that information from the configuration file.
C#
publicclass CalculatorService : ICalculator
{
publicdouble Add(double n1, double n2)
{
return n1 + n2;
}
publicdouble Subtract(double n1, double n2)
{
return n1 - n2;
}
publicdouble Multiply(double n1, double n2)
{
return n1 * n2;
}
publicdouble Divide(double n1, double n2)
Resource Links for 70-513 WCF Certification Exam
236
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
{
return n1 / n2;
}
}
3. Create a Web.config file to define the NetTcpBinding binding to be used by the
CalculatorService endpoints.
XML
<?xmlversion="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<bindingportSharingEnabled="true">
<securitymode="None" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
4. Create a Service.svc file that contains the following code.
5. <%@ServiceHost language=c# Service="CalculatorService" %>
6. Place the Service.svc file in your IIS virtual directory.
To create a client to use the service
1. Use ServiceModel Metadata Utility Tool (Svcutil.exe) from the command line to generate code
from service metadata.
2. Svcutil.exe <service's Metadata Exchange (MEX) address or HTTP GET address>
Note:
The address will depend on the location of the service file in your IIS virtual directory but will be
similar to the following address: et.tcp://localhost/servicemodelsamples/service.svc/mex
For the source copy of this example, which includes instructions for building, configuring, and
running the sample, see TCP Activation.
3. The client that is generated contains the ICalculator interface that defines the service contract
that the client implementation must satisfy.
C#
//Generated interface defining the ICalculator contract
[System.ServiceModel.ServiceContractAttribute(
Namespace="http://Microsoft.ServiceModel.Samples",
ConfigurationName="Microsoft.ServiceModel.Samples.ICalculator")]
publicinterface ICalculator
{
[System.ServiceModel.OperationContractAttribute(
Action="http://Microsoft.ServiceModel.Samples/ICalculator/Add",
ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")]
double Add(double n1, double n2);
[System.ServiceModel.OperationContractAttribute(
Action="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract",
ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractRespon
se")]
double Subtract(double n1, double n2);
[System.ServiceModel.OperationContractAttribute(
Resource Links for 70-513 WCF Certification Exam
237
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Action="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply",
ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyRespon
se")]
double Multiply(double n1, double n2);
[System.ServiceModel.OperationContractAttribute(
Action="http://Microsoft.ServiceModel.Samples/ICalculator/Divide",
ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse
")]
double Divide(double n1, double n2);
}
4. The generated client application also contains the implementation of the ClientCalculator. Note
that the address and binding information is not specified anywhere inside the implementation of
the service. Also, code does not have to be written to retrieve that information from the
configuration file.
C#
// Implementation of the CalculatorClient
publicpartialclass CalculatorClient :
System.ServiceModel.ClientBase<Microsoft.ServiceModel.Samples.ICalculator>,
Microsoft.ServiceModel.Samples.ICalculator
{
public CalculatorClient() { }
public CalculatorClient(string endpointConfigurationName) :
base(endpointConfigurationName) { }
public CalculatorClient(string endpointConfigurationName, string
remoteAddress) : base(endpointConfigurationName, remoteAddress){ }
public CalculatorClient(string endpointConfigurationName,
System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress) {}

public CalculatorClient(System.ServiceModel.Channels.Binding binding,
System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) { }
publicdouble Add(double n1, double n2)
{
returnbase.Channel.Add(n1, n2);
}
publicdouble Subtract(double n1, double n2)
{
returnbase.Channel.Subtract(n1, n2);
}
publicdouble Multiply(double n1, double n2)
{
returnbase.Channel.Multiply(n1, n2);
}
publicdouble Divide(double n1, double n2)
{
returnbase.Channel.Divide(n1, n2);
}
}
5. The configuration for the client that uses the NetTcpBinding is also generated by Svcutil.exe.
This file should be named in the App.config file when using Visual Studio.
C#

<?xml version="1.0" encoding="utf-8" ?>
Resource Links for 70-513 WCF Certification Exam
238
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_ICalculator">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost/servicemodelsamples/service.svc"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ICalculator"
contract="ICalculator" name="NetTcpBinding_ICalculator" />
</client>
</system.serviceModel>
</configuration>
None
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_ICalculator">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpointaddress="net.tcp://localhost/servicemodelsamples/service.svc"
binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ICalculator"
contract="ICalculator" name="NetTcpBinding_ICalculator" />
</client>
</system.serviceModel>
</configuration>
6. Create an instance of the ClientCalculator in an application and then call the service operations.
C#
//Client implementation code.
class Client
{
staticvoid Main()
{
// Create a client with given client endpoint configuration
CalculatorClient client = new CalculatorClient();
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
// Call the Subtract service operation.
value1 = 145.00D;
value2 = 76.54D;
result = client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);
// Call the Multiply service operation.
value1 = 9.00D;
Resource Links for 70-513 WCF Certification Exam
239
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
value2 = 81.25D;
result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
// Call the Divide service operation.
value1 = 22.00D;
value2 = 7.00D;
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
//Closing the client gracefully closes the connection and cleans up resources
client.Close();
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();
}
}
7. Compile and run the client.
Consuming Services (19%)
WCF Client Overview
This section describes what client applications do, how to configure, create, and use a Windows
Communication Foundation (WCF) client, and how to secure client applications.
Using WCF Client Objects
A client application is a managed application that uses a WCF client to communicate with
another application. To create a client application for a WCF service requires the following
steps:
1. Obtain the service contract, bindings, and address information for a service endpoint.
2. Create a WCF client using that information.
3. Call operations.
4. Close the WCF client object.
The following sections discuss these steps and provide brief introductions to the following
issues:
Handling errors.
Configuring and securing clients.
Creating callback objects for duplex services.
Calling services asynchronously.
Calling services using client channels.
Obtain the Service Contract, Bindings, and Addresses
Resource Links for 70-513 WCF Certification Exam
240
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
In WCF, services and clients model contracts using managed attributes, interfaces, and methods.
To connect to a service in a client application, you need to obtain the type information for the
service contract. Typically, you do this by using the ServiceModel Metadata Utility Tool
(Svcutil.exe), which downloads metadata from the service, converts it to a managed source code
file in the language of your choice, and creates a client application configuration file that you can
use to configure your WCF client object. For example, if you are going to create an WCF client
object to invoke a MyCalculatorService, and you know that the metadata for that service is
published at http://computerName/MyCalculatorService/Service.svc?wsdl, then the following code
example shows how to use Svcutil.exe to obtain a ClientCode.vb file that contains the service
contract in managed code.
svcutil /language:vb /out:ClientCode.vb /config:app.config
http://computerName/MyCalculatorService/Service.svc?wsdl
You can either compile this contract code into the client application or into another assembly that
the client application can then use to create an WCF client object. You can use the configuration
file to configure the client object to properly connect to the service .
For an example of this process, see How to: Create a Windows Communication Foundation
Client. For more complete information about contracts, see Contracts.
Create a WCF Client Object
A WCF client is a local object that represents a WCF service in a form that the client can use to
communicate with the remote service. WCF client types implement the target service contract, so
when you create one and configure it, you can then use the client object directly to invoke
service operations. The WCF run time converts the method calls into messages, sends them to
the service, listens for the reply, and returns those values to the WCF client object as return
values or out or ref parameters.
You can also use WCF client channel objects to connect with and use services. For details, see
Client Architecture.
Creating a New WCF Object
To illustrate the use of a ClientBase class, assume the following simple service contract has been
generated from a service application.
Note:
Resource Links for 70-513 WCF Certification Exam
241
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
If you are using Visual Studio to create your WCF client, objects are loaded automatically into
the object browser when you add a service reference to your project.
C#
[System.ServiceModel.ServiceContractAttribute( Namespace = "http://microsoft.wcf.documentation")]
publicinterface ISampleService
{
[System.ServiceModel.OperationContractAttribute(Action =
"http://microsoft.wcf.documentation/ISampleService/SampleMethod", ReplyAction =
"http://microsoft.wcf.documentation/ISampleService/SampleMethodResponse" )]
[System.ServiceModel.FaultContractAttribute(typeof(microsoft.wcf.documentation.SampleFault),
Action = "http://microsoft.wcf.documentation/ISampleService/SampleMethodSampleFaultFault" )]
string SampleMethod(string msg);
}

If you are not using Visual Studio, examine the generated contract code to find the type that
extends ClientBase and the service contract interface ISampleService. In this case, that type looks
like the following code:
C#
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
publicpartialclass SampleServiceClient : System.ServiceModel.ClientBase<ISampleService>, ISampleService
{
public SampleServiceClient() { }
public SampleServiceClient(string endpointConfigurationName) :base(endpointConfigurationName) { }
public SampleServiceClient(string endpointConfigurationName, string remoteAddress) :
base(endpointConfigurationName, remoteAddress) { }
public SampleServiceClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress
remoteAddress) :base(endpointConfigurationName, remoteAddress) { }
public SampleServiceClient(System.ServiceModel.Channels.Binding binding,
System.ServiceModel.EndpointAddress remoteAddress) :base(binding, remoteAddress) { }
publicstring SampleMethod(string msg)
{
returnbase.Channel.SampleMethod(msg);
}
}
Resource Links for 70-513 WCF Certification Exam
242
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
This class can be created as a local object using one of the constructors, configured, and then
used to connect to a service of the type ISampleService. It is recommended that you create your
WCF client object first, and then use it and close it inside a single try/catch block. You should
not use the using statement (Using in Visual Basic) because it may mask exceptions in certain
failure modes. For more information, see the following sections as well as Avoiding Problems
with the Using Statement.
Contracts, Bindings, and Addresses
Before you can create a WCF client object, you must configure the client object. Specifically, it
must have a service endpoint to use. An endpoint is the combination of a service contract, a
binding, and an address. (For more information about endpoints, see Endpoints: Addresses,
Bindings, and Contracts.) Typically, this information is located in the <endpoint> element in a
client application configuration file, such as the one the Svcutil.exe tool generates, and is loaded
automatically when you create your client object. Both WCF client types also have overloads
that enable you to programmatically specify this information. For example, a generated
configuration file for an ISampleService used in the preceding examples contains the following
endpoint information.
C#
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ISampleService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="None" proxyCredentialType="None"
Resource Links for 70-513 WCF Certification Exam
243
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8080/SampleService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ISampleService" contract="ISampleService"
name="WSHttpBinding_ISampleService">
</endpoint>
</client>
</system.serviceModel>
</configuration>
None
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ISampleService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
Resource Links for 70-513 WCF Certification Exam
244
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8080/SampleService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ISampleService" contract="ISampleService"
name="WSHttpBinding_ISampleService">
</endpoint>
</client>
</system.serviceModel>
</configuration>
This configuration file specifies a target endpoint in the <client> element. For more information
about using multiple target endpoints, see the
System.ServiceModel.ClientBase.#ctor(System.String) or the
System.ServiceModel.ChannelFactory.#ctor(System.String) constructors.
Calling Operations
Once you have a client object created and configured, create a try/catch block, call operations in
the same way that you would if the object were local, and close the WCF client object. When the
client application calls the first operation, WCF automatically opens the underlying channel, and
the underlying channel is closed when the object is recycled. (Alternatively, you can also
explicitly open and close the channel prior to or subsequent to calling other operations.)
For example, if you have the following service contract:
C#
namespace Microsoft.ServiceModel.Samples
{
using System;
using System.ServiceModel;

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
publicinterface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
Resource Links for 70-513 WCF Certification Exam
245
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
}
You can call operations by creating a WCF client object and calling its methods, as the following
code example demonstrates. Note that the opening, calling, and closing of the WCF client object
occurs within a single try/catch block. For more information, see Accessing Services Using a
Client and Avoiding Problems with the Using Statement.
C#
CalculatorClient wcfClient = new CalculatorClient();
try
{
Console.WriteLine(wcfClient.Add(4, 6));
wcfClient.Close();
}
catch (TimeoutException timeout)
{
// Handle the timeout exception.
wcfClient.Abort();
}
catch (CommunicationException commException)
{
// Handle the communication exception.
wcfClient.Abort();
}

Handling Errors
Exceptions can occur in a client application when opening the underlying client channel
(whether explicitly or automatically by calling an operation), using the client or channel object to
call operations, or when closing the underlying client channel. It is recommended at a minimum
that applications expect to handle possible System.TimeoutException and
System.ServiceModel.CommunicationException exceptions in addition to any
Resource Links for 70-513 WCF Certification Exam
246
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
System.ServiceModel.FaultException objects thrown as a result of SOAP faults returned by
operations. SOAP faults specified in the operation contract are raised to client applications as a
System.ServiceModel.FaultException where the type parameter is the detail type of the SOAP
fault. For more information about handling error conditions in a client application, see Sending
and Receiving Faults. For a complete sample the shows how to handle errors in a client, see
Expected Exceptions.
Configuring and Securing Clients
Configuring a client starts with the required loading of target endpoint information for the client
or channel object, usually from a configuration file, although you can also load this information
programmatically using the client constructors and properties. However, additional configuration
steps are required to enable certain client behavior and for many security scenarios.
For example, security requirements for service contracts are declared in the service contract
interface, and if Svcutil.exe created a configuration file, that file usually contains a binding that
is capable of supporting the security requirements of the service. In some cases, however, more
security configuration may be required, such as configuring client credentials. For complete
information about the configuration of security for WCF clients, see Securing Clients.
In addition, some custom modifications can be enabled in client applications, such as custom
run-time behaviors. For more information about how to configure a custom client behavior, see
Configuring Client Behaviors.
Creating Callback Objects for Duplex Services
Duplex services specify a callback contract that the client application must implement in order to
provide a callback object for the service to call according to the requirements of the contract.
Although callback objects are not full services (for example, you cannot initiate a channel with a
callback object), for the purposes of implementation and configuration they can be thought of as
a kind of service.
Clients of duplex services must:
Implement a callback contract class.
Create an instance of the callback contract implementation class and use it to create the
System.ServiceModel.InstanceContext object that you pass to the WCF client constructor.
Invoke operations and handle operation callbacks.
Resource Links for 70-513 WCF Certification Exam
247
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Duplex WCF client objects function like their nonduplex counterparts, with the exception that
they expose the functionality necessary to support callbacks, including the configuration of the
callback service.
For example, you can control various aspects of callback object runtime behavior by using
properties of the System.ServiceModel.CallbackBehaviorAttribute attribute on the callback
class. Another example is the use of the
System.ServiceModel.Description.CallbackDebugBehavior class to enable the return of
exception information to services that call the callback object. For more information, see Duplex
Services. For a complete sample, see Duplex.
On Windows XP computers running Internet Information Services (IIS) 5.1, duplex clients must
specify a client base address using the System.ServiceModel.WSDualHttpBinding class or an
exception is thrown. The following code example shows how to do this in code.
C#
WSDualHttpBinding dualBinding = new WSDualHttpBinding();
EndpointAddress endptadr = new EndpointAddress("http://localhost:12000/DuplexTestUsingCode/Server");
dualBinding.ClientBaseAddress = new Uri("http://localhost:8000/DuplexTestUsingCode/Client/");
The following code shows how to do this in a configuration file
C#
<client>
<endpoint name ="ServerEndpoint" address="http://localhost:12000/DuplexUsingConfig/Server"
bindingConfiguration="WSDualHttpBinding_IDuplex" binding="wsDualHttpBinding" contract="IDuplex" />
</client>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_IDuplex" clientBaseAddress="http://localhost:8000/myClient/" />
</wsDualHttpBinding>
</bindings>

Calling Services Asynchronously
How operations are called is entirely up to the client developer. This is because the messages that
make up an operation can be mapped to either synchronous or asynchronous methods when
expressed in managed code. Therefore, if you want to build a client that calls operations
Resource Links for 70-513 WCF Certification Exam
248
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
asynchronously, you can use Svcutil.exe to generate asynchronous client code using the /async
option. For more information, see How to: Call WCF Service Operations Asynchronously.
Calling Services Using WCF Client Channels
WCF client types extend ClientBase, which itself derives from
System.ServiceModel.IClientChannel interface to expose the underlying channel system. You
can invoke services by using the target service contract with the
System.ServiceModel.ChannelFactory class. For details, see Client Architecture.
Create a service proxy.This objective may include but is not limited to: using a proxy class or
channel factory to create a proxy; creating a proxy for an asynchronous communication; creating
a proxy for a duplex communicationThis objective does not include: SvcUtil command-line
switches
Accessing Services Using a WCF Client
After you create a service, the next step is to create a WCF client. A client application uses the
WCF client to communicate with the service. Client applications usually import a service's
metadata to generate WCF client code that can be used to invoke the service.
The basic steps for creating a WCF client include the following:
1. Compile the service code.
2. Use the ServiceModel Metadata Utility Tool (Svcutil.exe) to create the WCF client.
ServiceModel Metadata Utility Tool
The ServiceModel Metadata Utility Tool (Svcutil.exe) is a command-line tool for generating
code from metadata. The following use is an example of a basic Svcutil.exe command.
Svcutil.exe <service's Metadata Exchange (MEX) address or HTTP GET address>
Alternatively, you can use Svcutil.exe with Web Services Description Language (WSDL) and
XML Schema definition language (XSD) files on the file system.
Svcutil.exe <list of WSDL and XSD files on file system>The result is a code file that contains WCF client
code that the client application can use to invoke the service.You can also use the tool to
generate configuration files.Svcutil.exe <file1 [,file2]>If only one file name is given, that is the name
of the output file. If two file names are given, then the first file is an input configuration file
whose contents are merged with the generated configuration and written out into the second file.
Resource Links for 70-513 WCF Certification Exam
249
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
For more information about configuration, see Configuring Bindings for Windows
Communication Foundation Services.
Note:
Unsecured metadata requests pose certain risks in the same way that any unsecured network
request does: If you are not certain that the endpoint you are communicating with is who it says
it is, the information you retrieve might be metadata from a malicious service.
Example
The following code example shows a service contract created for a service.
C#
// Define a service contract.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
publicinterface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
// Other methods are not shown here.
}
VB
' Define a service contract.
<ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")> _
PublicInterface ICalculator
<OperationContract()> _
Function Add(ByVal n1 AsDouble, ByVal n2 AsDouble) AsDouble
' Other methods are not shown here.
EndInterface
The ServiceModel Metadata utility tool generates the following WCF client class. The class
inherits from the generic ClientBase class and implements the ICalculator interface. The tool also
generates the ICalculator interface (not shown here).
C#
publicpartialclass CalculatorClient : System.ServiceModel.ClientBase<ICalculator>, ICalculator
{
public CalculatorClient(){}
public CalculatorClient(string configurationName) :base(configurationName) {}
Resource Links for 70-513 WCF Certification Exam
250
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
public CalculatorClient(System.ServiceModel.Binding binding) :base(binding) {}
public CalculatorClient(System.ServiceModel.EndpointAddress address, System.ServiceModel.Binding binding)
:base(address, binding) {}
publicdouble Add(double n1, double n2)
{
returnbase.InnerChannel.Add(n1, n2);
}
}
Using the WCF Client
To use the WCF client, create an instance of the WCF client, and then call its methods, as shown
in the following code.
C#
// Create a client object with the given client endpoint configuration.
CalculatorClient calcClient = new CalculatorClient("CalculatorEndpoint"));
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = calcClient.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
Debugging Exceptions Thrown by a Client
Many exceptions thrown by a WCF client are caused by an exception on the service. Some
examples of this are:
SocketException: An existing connection was forcibly closed by the remote host.
CommunicationException: The underlying connection was closed unexpectedly.
CommunicationObjectAbortedException: The socket connection was aborted. This could be
caused by an error processing your message, a receive time-out being exceeded by the remote
host, or an underlying network resource issue.When these types of exceptions occur, the best
way to solve the problem is to turn on tracing on the service side and determine what exception
occurred there. For more information about tracing, see Tracing and Using Tracing to
Troubleshoot Your Application.
Resource Links for 70-513 WCF Certification Exam
251
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
How to: Call WCF Service Operations
Asynchronously
This topic covers how a client can access a service operation asynchronously. The service in this
topic implements the ICalculator interface. The client can call the operations on this interface
asynchronously by using the event-driven asynchronous calling model. (For more information
about the event-based asynchronous calling model, see Multithreaded Programming with the
Event-based Asynchronous Pattern). For an example that shows how to implement an operation
asynchronously in a service, see How to: Implement an Asynchronous Service Operation. For
more information about synchronous and asynchronous operations, see Synchronous and
Asynchronous Operations.
Note:
The event-driven asynchronous calling model is not supported when using a ChannelFactory.
For information about making asynchronous calls using the ChannelFactory, see How to: Call
Operations Asynchronously Using a Channel Factory.
Procedure
To call WCF service operations asynchronously
1. Run the ServiceModel Metadata Utility Tool (Svcutil.exe) tool with both the /async and the
/tcv:Version35 command options together as shown in the following command.
2. svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples
http://localhost:8000/servicemodelsamples/service/mex /a /tcv:Version35
This generates, in addition to the synchronous and standard delegate-based asynchronous
operations, a WCF client class that contains:
o Two <operationName>Async operations for use with the event-based asynchronous calling
approach. For example:
C#
publicvoid AddAsync(double n1, double n2)
{
this.AddAsync(n1, n2, null);
}
Resource Links for 70-513 WCF Certification Exam
252
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
publicvoid AddAsync(double n1, double n2, object userState)
{
if ((this.onBeginAddDelegate == null))
{
this.onBeginAddDelegate = new BeginOperationDelegate(this.OnBeginAdd);
}
if ((this.onEndAddDelegate == null))
{
this.onEndAddDelegate = new EndOperationDelegate(this.OnEndAdd);
}
if ((this.onAddCompletedDelegate == null))
{
this.onAddCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnAddCompleted);
}
base.InvokeAsync(this.onBeginAddDelegate, newobject[] {n1, n2}, this.onEndAddDelegate,
this.onAddCompletedDelegate, userState);
}
o Operation completed events of the form <operationName>Completed for use with the event-
based asynchronous calling approach. For example:
C#
publicevent System.EventHandler<AddCompletedEventArgs> AddCompleted;
o System.EventArgs types for each operation (of the form
<operationName>CompletedEventArgs) for use with the event-based asynchronous calling
approach. For example:
C#
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
publicpartialclass AddCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
privateobject[] results;
public AddCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
base(exception, cancelled, userState)
{ this.results = results; }
publicdouble Result
{
Resource Links for 70-513 WCF Certification Exam
253
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
get {
base.RaiseExceptionIfNecessary();
return ((double)(this.results[0]));
}
}
}
3. In the calling application, create a callback method to be called when the asynchronous operation
is complete, as shown in the following sample code.
C#
// Asynchronous callbacks for displaying results.
staticvoid AddCallback(object sender, AddCompletedEventArgs e)
{
Console.WriteLine("Add Result: {0}", e.Result);
}
4. Prior to calling the operation, use a new generic System.EventHandler of type
<operationName>EventArgs to add the handler method (created in the preceding step) to the
<operationName>Completed event. Then call the <operationName>Async method. For
example:
C#
// AddAsync
double value1 = 100.00D;
double value2 = 15.99D;
client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
client.AddAsync(value1, value2);
Console.WriteLine("Add({0},{1})", value1, value2);
Example
Note:
The design guidelines for the event-based asynchronous model state that if more than one value
is returned, one value is returned as the Result property and the others are returned as properties
on the EventArgs object. One result of this is that if a client imports metadata using the event-
based asynchronous command options and the operation returns more than one value, the default
EventArgs object returns one value as the Result property and the remainder are properties of
Resource Links for 70-513 WCF Certification Exam
254
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
the EventArgs object.If you want to receive the message object as the Result property and have
the returned values as properties on that object, use the /messageContract command option.
This generates a signature that returns the response message as the Result property on the
EventArgs object. All internal return values are then properties of the response message object.
C#
using System;
namespace Microsoft.ServiceModel.Samples
{
// The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.
class Client
{
staticvoid Main()
{
Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.");
Console.WriteLine();
// Create a client
CalculatorClient client = new CalculatorClient();
// AddAsync
double value1 = 100.00D;
double value2 = 15.99D;
client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
client.AddAsync(value1, value2);
Console.WriteLine("Add({0},{1})", value1, value2);
// SubtractAsync
value1 = 145.00D;
value2 = 76.54D;
client.SubtractCompleted += new EventHandler<SubtractCompletedEventArgs>(SubtractCallback);
client.SubtractAsync(value1, value2);
Console.WriteLine("Subtract({0},{1})", value1, value2);
// Multiply
value1 = 9.00D;
value2 = 81.25D;
double result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
// Divide
Resource Links for 70-513 WCF Certification Exam
255
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
value1 = 22.00D;
value2 = 7.00D;
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
Console.ReadLine();
//Closing the client gracefully closes the connection and cleans up resources
client.Close();
}
// Asynchronous callbacks for displaying results.
staticvoid AddCallback(object sender, AddCompletedEventArgs e)
{
Console.WriteLine("Add Result: {0}", e.Result);
}
staticvoid SubtractCallback(object sender, SubtractCompletedEventArgs e)
{
Console.WriteLine("Subtract Result: {0}", e.Result);
}
}
}

How to: Access Services with a Duplex
Contract
One feature of Windows Communication Foundation (WCF) is the ability to create a service that
uses a duplex messaging pattern. This pattern allows a service to communicate with the client
through a callback. This topic shows the steps to create a WCF client in a client class that
implements the callback interface.A dual binding exposes the IP address of the client to the
service. The client should use security to ensure that it connects only to services it trusts.
For a tutorial on creating a basic WCF service and client, see Getting Started Tutorial.
To access a duplex service
Resource Links for 70-513 WCF Certification Exam
256
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
1. Create a service that contains two interfaces. The first interface is for the service, the second is
for the callback. For more information about creating a duplex service, see How to: Create a
Duplex Contract.
2. Run the service.
3. Use the ServiceModel Metadata Utility Tool (Svcutil.exe) to generate contracts (interfaces) for
the client. For information about how to do this, see How to: Create a Windows Communication
Foundation Client.
4. Implement the callback interface in the client class, as shown in the following example.
C#
publicclass CallbackHandler : ICalculatorDuplexCallback
{
publicvoid Result(double result)
{
Console.WriteLine("Result ({0})", result);
}
publicvoid Equation(string equation)
{
Console.WriteLine("Equation({0})", equation);
}
}
VB
PublicClass CallbackHandler
Implements ICalculatorDuplexCallback
PublicSub Result (ByVal result AsDouble)
Console.WriteLine("Result ({0})", result)
EndSub
PublicSub Equation(ByVal equation AsString)
Console.Writeline("Equation({0})", equation)
EndSub
EndClass
5. Create an instance of the InstanceContext class. The constructor requires an instance of the client
class.
C#
InstanceContext site = new InstanceContext(new CallbackHandler());
Resource Links for 70-513 WCF Certification Exam
257
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
VB
Dim site As InstanceContext = New InstanceContext(new CallbackHandler())
6. Create an instance of the WCF client using the constructor that requires an InstanceContext
object. The second parameter of the constructor is the name of an endpoint found in the
configuration file.
C#
CalculatorDuplexClient wcfClient =
new CalculatorDuplexClient(site, "default")
VB
Dim wcfClient AsNew CalculatorDuplexClient(site, "default")
7. Call the methods of the WCF client as required.
Example
The following code example demonstrates how to create a client class that accesses a duplex
contract.
C#
ICalculatorDuplexCallback callback = null;
C#
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
// Define class that implements the callback interface of duplex
// contract.
publicclass CallbackHandler : ICalculatorDuplexCallback
{
publicvoid Result(double result)
{
Console.WriteLine("Result({0})", result);
}
publicvoid Equation(string equation)
{
Console.WriteLine("Equation({0})", equation);
}
}
publicclass Client
Resource Links for 70-513 WCF Certification Exam
258
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
{
publicstaticvoid Main()
{
// Picks up configuration from the config file.
CalculatorDuplexClient wcfClient = new CalculatorDuplexClient(new InstanceContext(new
CallbackHandler()));
try
{
// Call the AddTo service operation.
double value = 100.00D;
wcfClient.AddTo(value);
// Call the SubtractFrom service operation.
value = 50.00D;
wcfClient.SubtractFrom(value);
// Call the MultiplyBy service operation.
value = 17.65D;
wcfClient.MultiplyBy(value);
// Call the DivideBy service operation.
value = 2.00D;
wcfClient.DivideBy(value);
// Complete equation.
wcfClient.Clear();
// Wait for callback messages to complete before
// closing.
System.Threading.Thread.Sleep(5000);
// Close the WCF client.
wcfClient.Close();
Console.WriteLine("Done!");
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
wcfClient.Abort();
Console.Read();
}
catch (CommunicationException commProblem)
{
Resource Links for 70-513 WCF Certification Exam
259
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Console.WriteLine("There was a communication problem. " + commProblem.Message);
wcfClient.Abort();
Console.Read();
}
}
}

Configure client endpoints.This objective may include but is not limited to: standard bindings,
custom bindings created from standard binding elements, configuring behaviors; code-based and
configuration-based bindings; configuring addressesThis objective does not include: security;
creating custom behaviors
Client Configuration
You can use the Windows Communication Foundation (WCF) client configuration to specify the
address, binding, behavior, and contract, the "ABC" properties of the client endpoint, which
clients use to connect to service endpoints. The <client> element has an <endpoint> element
whose attributes are used to configure the endpoint ABCs. These attributes are discussed in the
"Configuring Endpoints" section of this topic.
The <endpoint> element also contains a <metadata> element that is used to specify settings for
importing and exporting metadata , a <headers> element that contains a collection of custom
address headers, and an <identity> element that enables the authentication of an endpoint by
other endpoints exchanging messages with it. The <headers> and <identity> elements are part of
the EndpointAddress and are discussed in the Endpoint Addresses topic. Links to topics that
explain the use of metadata extensions are provided in the Configuring Metadata sub-section of
this topic.
Configuring Endpoints
The client configuration is designed to allow the client to specify one or more endpoints, each
with its own name, address, and contract, with each referencing the <bindings> and <behaviors>
elements in the client configuration to be used to configure that endpoint. The client
configuration file should be named "App.config" because this is the name that the WCF runtime
expects. The following example shows a client configuration file.
Resource Links for 70-513 WCF Certification Exam
260
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<client>
<endpoint
name="endpoint1"
address="http://localhost/ServiceModelSamples/service.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IHello"
behaviorConfiguration="IHello_Behavior" contract="IHello" >
<metadata>
<wsdlImporters>
<extension type="Microsoft.ServiceModel.Samples.WsdlDocumentationImporter, WsdlDocumentation"/>
</wsdlImporters>
</metadata>
<identity>
<servicePrincipalName value="host/localhost" />
</identity>
</endpoint>
// Add another endpoint by adding another <endpoint> element.
<endpoint name="endpoint2">
//Configure another endpoint here.
</endpoint>
</client>
//The bindings section references by the bindingConfiguration endpoint attribute.
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IHello" bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard">
<readerQuotas maxDepth="32"/>
<reliableSession ordered="true" enabled="false" />
<security mode="Message">
//Security settings go here.
</security>
</binding>
<binding name="Another Binding"
//Configure this binding here.
</binding>
Resource Links for 70-513 WCF Certification Exam
261
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
</wsHttpBinding>
</bindings>
//The behavior section references by the behaviorConfiguration endpoint attribute.
<behaviors>
<endpointBehaviors>
<behavior name=" IHello_Behavior ">
<clientVia />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
The optional name attribute uniquely identifies an endpoint for a given contract. It is used by the
ChannelFactory or by the ClientBase to specify which endpoint in the client configuration is
being targeted and must be loaded when a channel is created to service. A wildcard endpoint
configuration name "*" is available and indicates to the ApplyConfiguration method that it
should load any endpoint configuration in the file, provided there is precisely one available, and
otherwise throws an exception. If this attribute is omitted, the corresponding endpoint is used as
the default endpoint associated with the specified contract type. The default value for the name
attribute is an empty string which is matched like any other name.
Every endpoint must have an address associated with it to locate and identify the endpoint. The
address attribute can be used to specify the URL that provides the location of the endpoint. But
the address for a service endpoint can also be specified in code by creating a Uniform Resource
Identifier (URI) and is added to the ServiceHost using one of the AddServiceEndpoint methods.
For more information, see Endpoint Addresses. As the introduction indicates, the <headers> and
<identity> elements are part of the EndpointAddress and are also discussed in the Endpoint
Addresses topic.The binding attribute indicates the type of binding the endpoint expects to use
when connecting to a service. The type must have a registered configuration section if it is to be
referenced. In the previous example, this is the <wsHttpBinding> section, which indicates that
the endpoint uses a WSHttpBinding. But there may be more than one binding of a given type that
the endpoint can use. Each of these has its own <binding> element within the (binding) type
element. The bindingconfiguration attribute is used to distinguish between bindings of the same
type. Its value is matched with the name attribute of the <binding> element. For more
Resource Links for 70-513 WCF Certification Exam
262
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
information about how to configure a client binding using configuration, see How to: Specify a
Client Binding in Configuration.The behaviorConfiguration attribute is used to specify which
<behavior> of the <endpointBehaviors> the endpoint should use. Its value is matched with the
name attribute of the <behavior> element. For an example of using configuration to specify
client behaviors, see Configuring Client Behaviors.The contract attribute specifies which
contract the endpoint is exposing. This value maps to the ConfigurationName of the
ServiceContractAttribute. The default value is the full type name of the class that implements the
service.
Configuring Metadata
The <metadata> element is used to specify settings used to register metadata import extensions.
For more information about extending the metadata system, see Extending the Metadata System.
Specifying Client Run-Time Behavior
Windows Communication Foundation (WCF) clients, like Windows Communication Foundation
(WCF) services, can be configured to modify the run-time behavior to suit the client application.
Three attributes are available for specifying client run-time behavior. Duplex client callback
objects can use the CallbackBehaviorAttribute and CallbackDebugBehavior attributes to modify
their run-time behavior. The other attribute, ClientViaBehavior, can be used to separate the
logical destination from the immediate network destination. In addition, duplex client callback
types can use some of the service-side behaviors. For more information, see Specifying Service
Run-Time Behavior.
Using the CallbackBehaviorAttribute
You can configure or extend the execution behavior of a callback contract implementation in a
client application by using the CallbackBehaviorAttribute class. This attribute performs a
similar function for the callback class as the ServiceBehaviorAttribute class, with the exception
of instancing behavior and transaction settings. The CallbackBehaviorAttribute class must be
applied to the class that implements the callback contract. If applied to a nonduplex contract
implementation, an InvalidOperationException exception is thrown at run time. The following
code example shows a CallbackBehaviorAttribute class on a callback object that uses the
SynchronizationContext object to determine the thread to marshal to, the
Resource Links for 70-513 WCF Certification Exam
263
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
ValidateMustUnderstand property to enforce message validation, and the
IncludeExceptionDetailInFaults property to return exceptions as FaultException objects to the
service for debugging purposes.
C#
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Threading;
namespace Microsoft.WCF.Documentation
{
[CallbackBehaviorAttribute( IncludeExceptionDetailInFaults= true, UseSynchronizationContext=true,
ValidateMustUnderstand=true )]
publicclass Client : SampleDuplexHelloCallback
{
AutoResetEvent waitHandle;
public Client()
{
waitHandle = new AutoResetEvent(false);
}
publicvoid Run()
{
// Picks up configuration from the configuration file.
SampleDuplexHelloClient wcfClient= new SampleDuplexHelloClient(new InstanceContext(this),
"WSDualHttpBinding_SampleDuplexHello");
try
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Enter a greeting to send and press ENTER: ");
Console.Write(">>> ");
Console.ForegroundColor = ConsoleColor.Green;
string greeting = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Called service with: \r\n\t" + greeting);
wcfClient.Hello(greeting);
Console.WriteLine("Execution passes service call and moves to the WaitHandle.");
this.waitHandle.WaitOne();
Resource Links for 70-513 WCF Certification Exam
264
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("Set was called.");
Console.Write("Press ");
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("ENTER");
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write(" to exit...");
Console.ReadLine();
}
catch (TimeoutException timeProblem)
{
Console.WriteLine("The service operation timed out. " + timeProblem.Message);
Console.ReadLine();
}
catch (CommunicationException commProblem)
{
Console.WriteLine("There was a communication problem. " + commProblem.Message);
Console.ReadLine();
}
}
publicstaticvoid Main()
{
Client client = new Client();
client.Run();
}
publicvoid Reply(string response)
{
Console.WriteLine("Received output.");
Console.WriteLine("\r\n\t" + response);
this.waitHandle.Set();
}
}
}
Using CallbackDebugBehavior to Enable the Flow of
Managed Exception Information
Resource Links for 70-513 WCF Certification Exam
265
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
You can enable the flow of managed exception information in a client callback object back to the
service for debugging purposes by setting the IncludeExceptionDetailInFaults property to true
either programmatically or from an application configuration file. Returning managed exception
information to services can be a security risk because exception details expose information about
the internal client implementation that unauthorized services could use. In addition, although the
CallbackDebugBehavior properties can also be set programmatically, it can be easy to forget to
disable IncludeExceptionDetailInFaults when deploying.
Because of the security issues involved, it is strongly recommended that:
You use an application configuration file to set the value of the
IncludeExceptionDetailInFaults property to true.
You do so only in controlled debugging scenarios.
The following code example shows a client configuration file that instructs WCF to return
managed exception information from a client callback object in SOAP messages.
Using the ClientViaBehavior Behavior
You can use the ClientViaBehavior behavior to specify the Uniform Resource Identifier for
which the transport channel should be created. Use this behavior when the immediate network
destination is not the intended processor of the message. This enables multiple-hop conversations
when the calling application does not necessarily know the ultimate destination or when the
destination Via header is not an address.
Invoke a service.This objective may include but is not limited to: invoking a service operation
synchronously and asynchronously; handling service faults ; using the Message class; managing
the life cycle of the proxy (open channels, close channels, abort channels, handle faulted
channels); implementing duplex communication
How to: Call WCF Service Operations
Asynchronously
This topic covers how a client can access a service operation asynchronously. The service in this
topic implements the ICalculator interface. The client can call the operations on this interface
asynchronously by using the event-driven asynchronous calling model. (For more information
Resource Links for 70-513 WCF Certification Exam
266
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
about the event-based asynchronous calling model, see Multithreaded Programming with the
Event-based Asynchronous Pattern). For an example that shows how to implement an operation
asynchronously in a service, see How to: Implement an Asynchronous Service Operation. For
more information about synchronous and asynchronous operations, see Synchronous and
Asynchronous Operations.
Note:
The event-driven asynchronous calling model is not supported when using a ChannelFactory.
For information about making asynchronous calls using the ChannelFactory, see How to: Call
Operations Asynchronously Using a Channel Factory.
Procedure
To call WCF service operations asynchronously
1. Run the ServiceModel Metadata Utility Tool (Svcutil.exe) tool with both the /async and the
/tcv:Version35 command options together as shown in the following command.
2. svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples
http://localhost:8000/servicemodelsamples/service/mex /a /tcv:Version35
This generates, in addition to the synchronous and standard delegate-based asynchronous
operations, a WCF client class that contains:
o Two <operationName>Async operations for use with the event-based asynchronous calling
approach. For example:
C#
publicvoid AddAsync(double n1, double n2)
{
this.AddAsync(n1, n2, null);
}
publicvoid AddAsync(double n1, double n2, object userState)
{
if ((this.onBeginAddDelegate == null))
{
this.onBeginAddDelegate = new BeginOperationDelegate(this.OnBeginAdd);
}
if ((this.onEndAddDelegate == null))
{
Resource Links for 70-513 WCF Certification Exam
267
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
this.onEndAddDelegate = new EndOperationDelegate(this.OnEndAdd);
}
if ((this.onAddCompletedDelegate == null))
{
this.onAddCompletedDelegate = new System.Threading.SendOrPostCallback(this.OnAddCompleted);
}
base.InvokeAsync(this.onBeginAddDelegate, newobject[] {n1, n2}, this.onEndAddDelegate,
this.onAddCompletedDelegate, userState);
}
o Operation completed events of the form <operationName>Completed for use with the event-
based asynchronous calling approach. For example:
C#
publicevent System.EventHandler<AddCompletedEventArgs> AddCompleted;
o System.EventArgs types for each operation (of the form
<operationName>CompletedEventArgs) for use with the event-based asynchronous calling
approach. For example:
C#
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
publicpartialclass AddCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
{
privateobject[] results;
public AddCompletedEventArgs(object[] results, System.Exception exception, bool cancelled, object userState) :
base(exception, cancelled, userState)
{ this.results = results; }
publicdouble Result
{
get {
base.RaiseExceptionIfNecessary();
return ((double)(this.results[0]));
}
}
}
3. In the calling application, create a callback method to be called when the asynchronous operation
is complete, as shown in the following sample code.
Resource Links for 70-513 WCF Certification Exam
268
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
C#
// Asynchronous callbacks for displaying results.
staticvoid AddCallback(object sender, AddCompletedEventArgs e)
{
Console.WriteLine("Add Result: {0}", e.Result);
}
4. Prior to calling the operation, use a new generic System.EventHandler of type
<operationName>EventArgs to add the handler method (created in the preceding step) to the
<operationName>Completed event. Then call the <operationName>Async method. For
example:
C#
// AddAsync
double value1 = 100.00D;
double value2 = 15.99D;
client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
client.AddAsync(value1, value2);
Console.WriteLine("Add({0},{1})", value1, value2);
Example
Note:
The design guidelines for the event-based asynchronous model state that if more than one value
is returned, one value is returned as the Result property and the others are returned as properties
on the EventArgs object. One result of this is that if a client imports metadata using the event-
based asynchronous command options and the operation returns more than one value, the default
EventArgs object returns one value as the Result property and the remainder are properties of
the EventArgs object.If you want to receive the message object as the Result property and have
the returned values as properties on that object, use the /messageContract command option.
This generates a signature that returns the response message as the Result property on the
EventArgs object. All internal return values are then properties of the response message object.
C#
using System;
namespace Microsoft.ServiceModel.Samples
{
Resource Links for 70-513 WCF Certification Exam
269
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
// The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.
class Client
{
staticvoid Main()
{
Console.WriteLine("Press <ENTER> to terminate client once the output is displayed.");
Console.WriteLine();
// Create a client
CalculatorClient client = new CalculatorClient();
// AddAsync
double value1 = 100.00D;
double value2 = 15.99D;
client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
client.AddAsync(value1, value2);
Console.WriteLine("Add({0},{1})", value1, value2);
// SubtractAsync
value1 = 145.00D;
value2 = 76.54D;
client.SubtractCompleted += new EventHandler<SubtractCompletedEventArgs>(SubtractCallback);
client.SubtractAsync(value1, value2);
Console.WriteLine("Subtract({0},{1})", value1, value2);
// Multiply
value1 = 9.00D;
value2 = 81.25D;
double result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);
// Divide
value1 = 22.00D;
value2 = 7.00D;
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);
Console.ReadLine();
//Closing the client gracefully closes the connection and cleans up resources
client.Close();
}
// Asynchronous callbacks for displaying results.
staticvoid AddCallback(object sender, AddCompletedEventArgs e)
Resource Links for 70-513 WCF Certification Exam
270
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
{
Console.WriteLine("Add Result: {0}", e.Result);
}
staticvoid SubtractCallback(object sender, SubtractCompletedEventArgs e)
{
Console.WriteLine("Subtract Result: {0}", e.Result);
}
}
}
Consume RESTful services.This objective may include but is not limited to: access HTTP
context; JSON/POX
Implement service Discovery.This objective may include but is not limited to: configuring target
scope; monitoring service announcements
WCF Discovery Overview
The Discovery APIs provide a unified programming model for the dynamic publication and
discovery of Web services using the WS-Discovery protocol. These APIs allow services to
publish themselves and clients to find published services. Once a service is made discoverable,
the service has the ability to send announcement messages as well as listen for and respond to
discovery requests. Discoverable services can send Hello messages to announce their arrival on a
network and Bye messages to announce their departure from a network. To find a service, clients
send a Probe request that contains specific criteria such as service contract type, keywords, and
scope on the network. Services receive the Probe request and determine whether they match the
criteria. If a service matches, it responds by sending a ProbeMatch message back to the client
with the information necessary to contact the service. Clients can also send Resolve requests that
allow them to find services that may have changed their endpoint address. Matching services
respond to Resolve requests by sending a ResolveMatch message back to the client.
Ad-Hoc and Managed Modes
The Discovery API supports two different modes: Managed and Ad-Hoc. In Managed mode
there is a centralized server called a discovery proxy that maintains information about available
services. The discovery proxy can be populated with information about services in a variety of
ways. For example, services can send announcement messages during start up to the discovery
Resource Links for 70-513 WCF Certification Exam
271
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
proxy or the proxy may read data from a database or a configuration file to determine what
services are available. How the discovery proxy is populated is completely up to the developer.
Clients use the discovery proxy to retrieve information about available services. When a client
searches for a service it sends a Probe message to the discovery proxy and the proxy determines
whether any of the services it knows about match the service the client is searching for. If there
are matches the discovery proxy sends a ProbeMatch response back to the client. The client can
then contact the service directly using the service information returned from the proxy. The key
principle behind Managed mode is that the discovery requests are sent in a unicast manner to one
authority, the discovery proxy. The .NET Framework contains key components that allow you to
build your own proxy. Clients and services can locate the proxy by multiple methods:
The proxy can respond to ad-hoc messages.
The proxy can send an announcement message during start up.
Clients and services can be written to look for a specific well-known endpoint.
In Ad-Hoc mode, there is no centralized server. All discovery messages such as service
announcements and client requests are sent in a multicast fashion. By default the .NET
Framework contains support for Ad-Hoc discovery over the UDP protocol. For example, if a
service is configured to send out a Hello announcement on start up, it sends it out over a well-
known, multicast address using the UDP protocol. Clients have to actively listen for these
announcements and process them accordingly. When a client sends a Probe message for a
service it is sent over the network using a multicast protocol. Each service that receives the
request determines whether it matches the criteria in the Probe message and responds directly to
the client with a ProbeMatch message if the service matches the criteria specified in the Probe
message.
Benefits of Using WCF Discovery
Because WCF Discovery is implemented using the WS-Discovery protocol it is interoperable
with other clients, services, and proxies that implement WS-Discovery as well. WCF Discovery
is built upon the existing WCF APIs, which makes it easy to add Discovery functionality to your
existing services and clients. Service discoverability can be easily added through the application
configuration settings. In addition, WCF Discovery also supports using the discovery protocol
over other transports such as peer net, naming overlay, and HTTP. WCF Discovery provides
Resource Links for 70-513 WCF Certification Exam
272
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
support for a Managed mode of operation where a discovery proxy is used. This can reduce
network traffic as messages are sent directly to the discovery proxy instead of sending multicast
messages to the entire network. WCF Discovery also allows for more flexibility when working
with Web services. For example, you can change the address of a service without having to
reconfigure the client or the service. When a client must access the service it can issue a Probe
message through a Find request and expect the service to respond with its current address. WCF
Discovery allows a client to search for a service based on different criteria including contract
types, binding elements, namespace, scope, and keywords or version numbers. WCF Discovery
enables runtime and design time discovery. Adding discovery to your application can be used to
enable other scenarios such as fault tolerance and auto configuration.
Service Publication
To make a service discoverable, a ServiceDiscoveryBehavior must be added to the service host
and a discovery endpoint must be added to specify where to listen for discovery messages. The
following code example shows how a self-hosted service can be modified to make it
discoverable.
Uri baseAddress = new Uri(string.Format("http://{0}:8000/discovery/scenarios/calculatorservice/{1}/",
System.Net.Dns.GetHostName(), Guid.NewGuid().ToString()));
// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
// add calculator endpoint
serviceHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), string.Empty);
// ** DISCOVERY ** //
// make the service discoverable by adding the discovery behavior
serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
// ** DISCOVERY ** //
// add the discovery endpoint that specifies where to publish the services
serviceHost.AddServiceEndpoint(new UdpDiscoveryEndpoint());
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("Press <ENTER> to terminate service.");
Console.ReadLine();
Resource Links for 70-513 WCF Certification Exam
273
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
}
A ServiceDiscoveryBehavior instance must be added to a service description for the service to
be discoverable. A DiscoveryEndpoint instance must be added to the service host to tell the
service where to listen for discovery requests. In this example, a UdpDiscoveryEndpoint (which
is derived from DiscoveryEndpoint) is added to specify that the service should listen for
discovery requests over the UDP multicast transport. The UdpDiscoveryEndpoint is used for
Ad-Hoc discovery because all messages are sent in a multicast fashion.
Announcement
By default, service publication does not send out announcement messages. The service must be
configured to send out announcement messages. This provides additional flexibility for service
writers because they can announce the service separately from listening for discovery messages.
Service announcement can also be used as a mechanism for registering services with a discovery
proxy or other service registries. The following code shows how to configure a service to send
announcement messages over a UDP binding.
Uri baseAddress = new Uri(string.Format("http://{0}:8000/discovery/scenarios/calculatorservice/{1}/",
System.Net.Dns.GetHostName(), Guid.NewGuid().ToString()));
// Create a ServiceHost for the CalculatorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(CalculatorService), baseAddress))
{
// add calculator endpoint
serviceHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), string.Empty);
// ** DISCOVERY ** //
// make the service discoverable by adding the discovery behavior
ServiceDiscoveryBehavior discoveryBehavior = new ServiceDiscoveryBehavior();
serviceHost.Description.Behaviors.Add(new ServiceDiscoveryBehavior());
// send announcements on UDP multicast transport
discoveryBehavior.AnnouncementEndpoints.Add( new UdpAnnouncementEndpoint());
// ** DISCOVERY ** //
// add the discovery endpoint that specifies where to publish the services
serviceHost.Description.Endpoints.Add(new UdpDiscoveryEndpoint());
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("Press <ENTER> to terminate service.");
Resource Links for 70-513 WCF Certification Exam
274
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Console.ReadLine();
}
Service Discovery
A client application can use the DiscoveryClient class to find services. The developer creates an
instance of the DiscoveryClient class that passes in a discovery endpoint that specifies where to
send Probe or Resolve messages. The client then calls Find that specifies search criteria within a
FindCriteria instance. If matching services are found, Find returns a collection of
EndpointDiscoveryMetadata. The following code shows how to call the Find method and then
connect to a discovered service.
class Client
{
static EndpointAddress serviceAddress;
static void Main()
{
if (FindService()) InvokeService();
}
// ** DISCOVERY ** //
static bool FindService()
{
Console.WriteLine("\nFinding Calculator Service ..");
DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
Collection<EndpointDiscoveryMetadata> calculatorServices = discoveryClient.Find(new
FindCriteria(typeof(ICalculator)));
discoveryClient.Close();
if (calculatorServices.Count == 0)
{
Console.WriteLine("\nNo services are found.");
return false;
}
else
{
serviceAddress = calculatorServices[0].EndpointAddress;
return true;
}
}
Resource Links for 70-513 WCF Certification Exam
275
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
static void InvokeService()
{
Console.WriteLine("\nInvoking Calculator Service at {0}\n", serviceAddress);
// Create a client
CalculatorClient client = new CalculatorClient();
client.Endpoint.Address = serviceAddress;
client.Add(10,3);
}
Discovery and Message Level Security
When using message level security it is necessary to specify an EndpointIdentity on the service
discovery endpoint and a matching EndpointIdentity on the client discovery endpoint. For more
information about message level security, see Message Security in WCF.
Discovery and Web Hosted Services
In order for WCF services to be discoverable they must be running. WCF services hosted under
IIS or WAS do not run until IIS/WAS receives a message bound for the service, so they cannot
be discoverable by default. There are two options for making Web-Hosted services discoverable:
1. Use the Windows Server AppFabric Auto-Start feature
2. Use a discovery proxy to communicate on behalf of the service
Windows Server AppFabric has an Auto-Start feature that will allow a service to be started
before receiving any messages. With this Auto-Start set, an IIS/WAS hosted service can be
configured to be discoverable. For more information about the Auto-Start feature see, Windows
Server AppFabric Auto-Start Feature. Along with turning on the Auto-Start feature, you must
configure the service for discovery. For more information, see How to: Programmatically Add
Discoverability to a WCF Service and ClientConfiguring Discovery in a Configuration File.
A discovery proxy can be used to communicate on behalf of the WCF service when the service is
not running. The proxy can listen for probe or resolve messages and respond to the client. The
client can then send messages directly to the service. When the client sends a message to the
service it will be instantiated to respond to the message. For more information about
implementing a discovery proxy see, Implementing a Discovery Proxy.

Securing Services (17%)
Resource Links for 70-513 WCF Certification Exam
276
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Windows Communication Foundation
Security
The topics in this section describe Windows Communication Foundation (WCF) security
features and how to use them to help secure messages.
In This Section
Security OverviewDescribes the security features in WCF.
Security ConceptsDescribes the basic terminology and concepts used in WCF security.
Common Security ScenariosDescribes scenarios and topologies you can configure with WCF.
Bindings and SecurityA security-oriented view of the bindings, including topics that demonstrate
how to create custom security bindings.
Securing Services and ClientsDescribes how to secure messages using WCF security features.
AuthenticationDemonstrates common authentication tasks.
AuthorizationDescribes common authorization scenarios with security implementations.
Federation and Issued TokensDescribes the basics of federation and how to create clients that
communicate with federated servers.
Partial TrustDescribes how to run partially-trusted scenarios and WCF limitations when running
partially trusted.
Auditing Security EventsDescribes how to audit security events.
Security Guidance and Best PracticesGuidelines for creating secure WCF applications.
Security Overview
Windows Communication Foundation (WCF) is a SOAP message-based distributed
programming platform, and securing messages between clients and services is essential to
protecting data. WCF provides a versatile and interoperable platform for exchanging secure
messages based upon both the existing security infrastructure and the recognized security
standards for SOAP messages.WCF uses concepts that are familiar if you have built secure,
distributed applications with existing technologies such as HTTPS, Windows integrated security,
or user names and passwords to authenticate users. WCF not only integrates with existing
security infrastructures, but also extends distributed security beyond Windows-only domains by
using secure SOAP messages. Consider WCF an implementation of existing security
mechanisms with the major advantage of using SOAP as the protocol in addition to existing
protocols. For example, credentials that identify a client or a service, such as user name and
password or X.509 certificates, have interoperable XML-based SOAP profiles. Using these
profiles, messages are exchanged securely by taking advantage of open specifications like XML
digital signatures and XML encryption. For a list of specifications, see Web Services Protocols
Supported by System-Provided Interoperability Bindings.Another parallel is the Component
Object Model (COM) on the Windows platform, which enables secure, distributed applications.
COM has a comprehensive security mechanism whereby security context can be flowed between
components; this mechanism enforces integrity, confidentiality, and authentication. However
COM does not enable cross-platform, secure messaging like WCF does. Using WCF, you can
build services and clients that span from Windows domains across the Internet. The interoperable
messages of WCF are essential for building dynamic, business-driven services that help you feel
confident in the security of your information.
Resource Links for 70-513 WCF Certification Exam
277
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Windows Communication Foundation Security Benefits
WCF is a distributed programming platform based on SOAP messages. Using WCF, you can
create applications that function as both services and service clients, creating and processing
messages from an unlimited number of other services and clients. In such a distributed
application, messages can flow from node to node, through firewalls, onto the Internet, and
through numerous SOAP intermediaries. This introduces a variety of message security threats.
The following examples illustrate some common threats that WCF security can help mitigate
when exchanging messages between entities:
Observation of network traffic to obtain sensitive information. For example, in an online-banking
scenario, a client requests the transfer of funds from one account to another. A malicious user
intercepts the message and, having the account number and password, later performs a transfer of
funds from the compromised account.
Rogue entities acting as services without awareness of the client. In this scenario, a malicious user (the
rogue) acts as an online service and intercepts messages from the client to obtain sensitive information.
Then the rogue uses the stolen data to transfer funds from the compromised account. This attack is also
known a phishing attack.
Alteration of messages to obtain a different result than the caller intended. For example, altering the
account number to which a deposit is made allows the funds to go to a rogue account.
Hacker replays in which a nuisance hacker replays the same purchase order. For example, an online
bookstore receives hundreds of orders and sends the books to a customer who has not ordered them.
Inability of a service to authenticate a client. In this case, the service cannot assure that the appropriate
person performed the transaction.
In summary, transfer security provides the following assurances:
Service endpoint (respondent) authentication.
Client principal (initiator) authentication.
Message integrity.
Message confidentiality.
Replay detection.
Integration with Existing Security Infrastructures
Often, Web service deployments have existing security solutions in place, for example, Secure
Sockets Layer (SSL) or the Kerberos protocol. Some take advantage of a security infrastructure
that has already been deployed, such as Windows domains using Active Directory. It is often
necessary to integrate with these existing technologies while evaluating and adopting newer
ones. WCF security integrates with existing transport security models and can leverage existing
infrastructure for newer transfer security models based on SOAP message security.
Integration with Existing Authentication Models
An important part of any communication security model is the ability to identify and authenticate
entities in communication. These entities in communication use "digital identities," or
credentials, to authenticate themselves with the communicating peers. As distributed
communication platforms evolved, various credential authentication and related security models
have been implemented. For example, on the Internet, the use of a user name and password to
identify users is common. On the intranet, the use of a Kerberos domain controller to back up
user and service authentication is becoming common. In certain scenarios, such as between two
business partners, certificates may be used to mutually authenticate the partners.
Resource Links for 70-513 WCF Certification Exam
278
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Thus, in the world of Web services, where the same service might be exposed to internal
corporate customers as well as to external partners or Internet customers, it is important that the
infrastructure provide for integration with these existing security authentication models. WCF
security supports a wide variety of credential types (authentication models) including:
Anonymous caller.
User name client credential.
Certificate client credential.
Windows (both Kerberos protocol and NT LanMan [NTLM]).
Standards and Interoperability
In a world with large existing deployments, homogeneity is rare. Distributed
computing/communications platforms need to interoperate with the technologies different
vendors offer. Likewise, security must also be interoperable.To enable interoperable security
systems, companies active in the Web services industry have authored a variety of standards.
Specifically regarding security, a few notable standards have been proposed: WS-Security:
SOAP Message Security (accepted by the OASIS standards body and formerly known as WS-
Security), WS-Trust, WS-SecureConversation, and WS-SecurityPolicy. WCF supports a wide
variety of interoperability scenarios. The BasicHttpBinding class is targeted at the Basic Security
Profile (BSP) and the WSHttpBinding class is targeted at the latest security standards, such as
WS-Security 1.1 and WS-SecureConversation. By adhering to these standards, WCF security can
interoperate and integrate with Web services that are hosted on operating systems and platforms
other than Microsoft Windows.
WCF Security Functional Areas
WCF security is divided into three functional areas: transfer security, access control, and
auditing. The following sections briefly discuss these areas and provide links for more
information.
Transfer Security
Transfer security encompasses three major security functions: integrity, confidentiality, and
authentication. Integrity is the ability to detect whether a message has been tampered with.
Confidentiality is the ability to keep a message unreadable by anyone other than the intended
recipient; this is achieved through cryptography. Authentication is the ability to verify a claimed
identity. Together, these three functions help to ensure that messages securely arrive from one
point to another.
Transport and Message Security Modes
Two main mechanisms are used to implement transfer security in WCF: transport security mode
and message security mode.
Transport security mode uses a transport-level protocol, such as HTTPS, to achieve transfer security.
Transport mode has the advantage of being widely adopted, available on many platforms, and less
computationally complex. However, it has the disadvantage of securing messages only from point-to-
point.
Message security mode, on the other hand, uses WS-Security (and other specifications) to implement
transfer security. Because the message security is applied directly to the SOAP messages and is
contained inside the SOAP envelopes, together with the application data, it has the advantage of being
transport protocol-independent, more extensible, and ensuring end-to-end security (versus point-to-
point); it has the disadvantage of being several times slower than transport security mode because it has
to deal with the XML nature of the SOAP messages.
Resource Links for 70-513 WCF Certification Exam
279
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
For more information about these differences, see Securing Services and Clients.
A third security mode uses both previous modes and brings advantages of both. This mode is
called TransportWithMessageCredential. In this mode, message security is used to
authenticate the client and transport security is used to authenticate the server and provide
message confidentiality and integrity. Thanks to this, the TransportWithMessageCredential
security mode is almost as fast as transport security mode and provides client authentication
extensibility in the same way as message security. However, unlike message security mode, it
does not provide complete end-to-end security.
Access Control
Access control is also known as authorization. Authorization allows different users to have
different privileges to view data. For example, because a company's human resources files
contain sensitive employee data, only managers are allowed to view employee data. Further,
managers can view only data for their direct reports. In this case, access control is based on both
the role ("manager") as well as the specific identity of the manager (to prevent one manager from
looking at another manager's employee records). In WCF, access control features are provided
through integration with the common language runtime (CLR) PrincipalPermissionAttribute and
through a set of APIs known as the identity model. For details about access control and claims-
based authorization, see Extending Security.
Auditing
Auditing is the logging of security events to the Windows event log. You can log security-related
events, such as authentication failures (or successes). For more information, see Auditing
Security Events. For programming details, see How to: Audit Windows Communication
Foundation Security Events.
Security Concepts
This section briefly explains the concepts associated with Windows Communication Foundation
(WCF) security.
In This Section
Security Concepts Used in WCFA high-level overview of concepts used in security implementations.
Distributed Application SecurityAn overview of how WCF provides security in distributed application
topography.
WCF Security TerminologyA glossary of terms used when discussing WCF security.
Reference
System.ServiceModel
System.ServiceModel.Channels
System.ServiceModel.Description
System.ServiceModel.Security
System.Security
Related Sections
Extending Security
Common Security Scenarios
Resource Links for 70-513 WCF Certification Exam
280
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The topics in this section catalog a number of possible client and service security configurations.
Configurations vary according to a number of factors. For example, whether a service or client is
on an intranet, or whether the security is provided by Windows or transport (such as HTTPS).
In This Section
Internet Unsecured Client and ServiceAn example of a public, unsecured client and service.
Intranet Unsecured Client and ServiceA basic Windows Communication Foundation (WCF) service
developed to provide information on a secure private network to a WCF application.
Transport Security with Basic AuthenticationThe application allows clients to log on using custom
authentication.
Transport Security with Windows AuthenticationShows a client and service secured by Windows
security.
Transport Security with an Anonymous ClientThis scenario uses transport security (such as HTTPS) to
ensure confidentiality and integrity.
Transport Security with Certificate AuthenticationShows a client and service secured by a certificate.
Message Security with an Anonymous ClientShows a client and service secured by WCF message
security.
Message Security with a User Name ClientThe client is a Windows Forms application that allows clients
to log on using a domain user name and password.
Message Security with a Certificate ClientServers have certificates, and each client has a certificate. A
security context is established through Transport Layer Security (TLS) negotiation.
Message Security with a Windows ClientA variation of the certificate client. Servers have certificates,
and each client has a certificate. A security context is established through TLS negotiation.
Message Security with a Windows Client without Credential NegotiationShows a client and service
secured by a Kerberos domain.
Message Security with Mutual CertificatesServers have certificates, and each client has a certificate. The
server certificate is distributed with the application and is available out of band.
Message Security with Issued TokensFederated security that enables the establishment of trust between
independent domains.
Trusted SubsystemA client accesses one or more Web services that are distributed across a network.
The Web services access additional resources (such as databases or other Web services) that must be
secured.
Reference
System.ServiceModel
Related Sections
Authorization
Security Overview
Windows Communication Foundation Security
Bindings and Security
Securing Services and Clients
Authentication
Authorization
Resource Links for 70-513 WCF Certification Exam
281
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Federation and Issued Tokens
Auditing Security Events
Bindings and Security
The system-provided bindings included with Windows Communication Foundation (WCF) offer
a quick way to program WCF applications. With one exception, all the bindings have a default
security scheme enabled. This topic helps you select the right binding for your security needs.
For an overview of WCF security, see Security Overview. For more information about
programming WCF using bindings, see Programming WCF Security.If you have already selected
a binding, you can find out more about the run-time behaviors that are associated with security in
Security Behaviors in WCF.Some security functions are not programmable using the system-
provided bindings. For more control using a custom binding, see Security Capabilities with
Custom Bindings.
Security Functions of Bindings
WCF includes a number of system-provided bindings that meet most needs. If a particular
binding does not suffice, you can also create a custom binding. For a list of system-provided
bindings, see System-Provided Bindings. For more information about custom bindings, see
Custom Bindings.Every binding in WCF has two forms: as an API and as an XML element used
in a configuration file. For example, the WSHttpBinding (API) has a counterpart in the
wsHttpBinding Element. The following section lists both forms for each binding and summarizes
the security features.
BasicHttp
In code, use the BasicHttpBinding class; in configuration, use the basicHttpBinding Element.
This binding is designed for use with a range of existing technologies, including the following:
ASP.NET Web services (ASMX), version 1.
Web Service Enhancements (WSE) applications.
Basic Profile as defined in the Web Services Interoperability (WS-I) specification
(http://go.microsoft.com/fwlink/?LinkId=38955).
Basic security profile as defined in WS-I.
By default, this binding is not secure. It is designed to interoperate with ASMX services. When
security is enabled, the binding is designed for seamless interoperation with Internet Information
Services (IIS) security mechanisms, such as basic authentication, digest, and integrated Windows
security. For more information, see Transport Security Overview. This binding supports the
following:
HTTPS transport security.
HTTP basic authentication.
WS-Security.
For more information, see BasicHttpSecurity, BasicHttpMessageSecurity,
BasicHttpMessageCredentialType, and BasicHttpSecurityMode.
WSHttpBinding
In code, use the WSHttpBinding class; in configuration, use the wsHttpBinding Element.
By default, this binding implements the WS-Security specification and provides interoperability
with services that implement the WS-* specifications. It supports the following:
HTTPS transport security.
WS-Security.
Resource Links for 70-513 WCF Certification Exam
282
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
HTTPS transport protection with SOAP message credential security for authenticating the caller.
For more information, see WSHttpSecurity, MessageSecurityOverHttp, MessageCredentialType,
SecurityMode, HttpTransportSecurity, HttpClientCredentialType, and HttpProxyCredentialType.
WSDualHttpBinding
In code, use the WSDualHttpBinding class; in configuration, use the wsDualHttpBinding
Element.
This binding is designed to enable duplex service applications. This binding implements the WS-
Security specification for message-based transfer security. Transport security is not available. By
default, it provides the following features:
Implements WS-Reliable Messaging for reliability.
Implements WS-Security for transfer security and authentication.
Uses HTTP for message delivery.
Uses text/XML message encoding.
Using WS-Security (message-layer security), the binding allows you to configure the following
parameters:
The security algorithm suite to determine the cryptographic algorithm.
Binding options for the following:
o Providing service credentials available out-of-band at the client.
o Providing service credentials negotiated from the service as part of channel setup.
For more information, see WSDualHttpSecurity and WSDualHttpSecurityMode.
NetTcpBinding
In code, use the NetTcpBinding class; in configuration, use the netTcpBinding Element.
This binding is optimized for cross-machine communication. By default, it has the following
characteristics:
Implements transport-layer security.
Leverages Windows security for transfer security and authentication.
Uses TCP for transport.
Implements binary message encoding.
Implements WS-Reliable Messaging.
Options include the following:
Message-layer security (using WS-Security).
Transport security with message credentialconfidentiality and integrity provided by Transport Layer
Security (TLS) over TCP, and credentials for authorization provided by WS-Security.
For more information, see NetTcpSecurity, TcpTransportSecurity, TcpClientCredentialType,
MessageSecurityOverTcp, and MessageCredentialType.
NetNamedPipeBinding
In code, use the NetNamedPipeBinding class; in configuration, use the netNamedPipeBinding
Element.
This binding is optimized for cross-process communication (usually on the same machine). By
default, this binding has the following characteristics:
Uses transport security for message transfer and authentication.
Uses named pipes for message delivery.
Implements binary message encoding.
Encryption and message signing.
Options include the following:
Authentication using Windows security.
Resource Links for 70-513 WCF Certification Exam
283
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
For more information, see NetNamedPipeSecurity, NetNamedPipeSecurityMode, and
NamedPipeTransportSecurity.
MsmqIntegrationBinding
In code, use the MsmqIntegrationBinding class; in configuration, use the
msmqIntegrationBinding element.
This binding is optimized for creating WCF clients and services that interoperate with non-WCF
Microsoft Message Queuing (MSMQ) endpoints.
By default, this binding uses transport security and provides the following security
characteristics:
Security can be disabled (None).
MSMQ transport security (Transport).
For more information, see NetMsmqSecurity and NetMsmqSecurityMode.
NetMsmqBinding
In code, use the NetMsmqBinding class; in configuration, use the netMsmqBinding Element.
This binding is intended for use when creating WCF services that require MSMQ queued
message support.
By default, this binding uses transport security and provides the following security
characteristics:
Security can be disabled (None).
MSMQ transport security (Transport).
SOAP-based message security (Message).
Simultaneous Transport and Message security (Both).
Client Credential Types supported: None, Windows, UserName, Certificate, IssuedToken.
The Certificate credential is supported only when the security mode is set to either Both or
Message.
For more information, see MessageSecurityOverMsmq and MsmqTransportSecurity.
WSFederationHttpBinding
In code, use the WSFederationHttpBinding class; in configuration, use the
WSFederationHttpBinding element.
By default, this binding uses WS-Security (message-layer security).
For more information, see Federation, WSFederationHttpSecurity, and
WSFederationHttpSecurityMode.
Custom Bindings
If none of the system-provided bindings meets you requirements, you can create a custom
binding with a custom security binding element. For more information, see Security Capabilities
with Custom Bindings.
Binding Choices
The following table summarizes the features offered in the security mode setting, that is, it lists
the features available when the security mode is set to Transport, Message, or
TransportWithMessageCredential. Use this table to help you find the security features your
application requires.
Setting Features
Transport
Server authentication
Client authentication
Resource Links for 70-513 WCF Certification Exam
284
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Point-to-point security
Interoperability
Hardware acceleration
High throughput
Secure firewall
High-latency applications
Re-encryption across multiple hops
Message
Server authentication
Client authentication
End-to-end security
Interoperability
Rich claims
Federation
Multifactor authentication
Custom tokens
Notary/timestamp service
High-latency applications
Persistence of message signatures
TransportWithMessageCredential
Server authentication
Client authentication
Point-to-point security
Interoperability
Hardware acceleration
High throughput
Rich client claims
Federation
Multifactor authentication
Custom tokens
Secure firewall
High-latency applications
Re-encryption across multiple hops
The following table lists the bindings that support the various mode settings. Select a binding
from the table to use to create your service endpoint.
Binding
Transport mode
support
Message mode
support
TransportWithMessageCredential
support
BasicHttpBinding Yes Yes Yes
WSHttpBinding Yes Yes Yes
WSDualHttpBinding No Yes No
NetTcpBinding Yes Yes Yes
NetNamedPipeBinding Yes No No
NetMsmqBinding Yes Yes No
MsmqIntegrationBinding Yes No No
Resource Links for 70-513 WCF Certification Exam
285
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
wsFederationHttpBinding No Yes Yes
Transport Credentials in Bindings
The following table lists the client credential types available when using either
BasicHttpBinding or WSHttpBinding in transport security mode.
Type Description
None
Specifies that the client does not need to present any credential. This translates to
an anonymous client.
Basic
Basic authentication. For more information, see RFC 2617 HTTP Authentication:
Basic and Digest Authentication, available at
http://go.microsoft.com/fwlink/?LinkId=84023.
Digest
Digest authentication. For more information, see RFC 2617 HTTP
Authentication: Basic and Digest Authentication, available at
http://go.microsoft.com/fwlink/?LinkId=84023.
NTLM NT LAN Manager (NTLM) authentication.
Windows Windows authentication.
Certificate Authentication performed using a certificate.
IssuedToken
Allows the service to require that the client be authenticated using a token issued
by a security token service or by CardSpace. For more information, see Federation
and Issued Tokens.
Message Client Credentials in Bindings
The following table lists the client credential types available when using a binding in Message
security mode.
Type Description
None Allows the service to interact with anonymous clients.
Windows
Allows SOAP message exchanges to be made under the authenticated context of a
Windows credential.
UserName
Allows the service to require that the client be authenticated using a user name
credential. Note that when the security mode is set to
TransportWithMessageCredential, WCF does not support sending a password
digest or deriving keys using password and using such keys for Message mode
security. As such, WCF enforces that the transport is secured when using user
name credentials.
Certificate Allows the service to require that the client be authenticated using a certificate.
IssuedToken Allows the service to use a security token service to supply a custom token.
Securing Services and Clients
The information in this section focuses on programming security in Windows Communication
Foundation (WCF). Generally, this includes selecting an appropriate system-provided binding,
setting the properties of the security element, and then setting properties of the service behaviors
that govern how credentials are retrieved for use by either the service or the client. These
Resource Links for 70-513 WCF Certification Exam
286
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
techniques cover the security requirements of most users for most scenarios, as shown in
Common Security Scenarios. If your scenario requires more capabilities, first see Security
Capabilities with Custom Bindings; if a solution is not apparent, see Extending Security. If you
are creating (or interoperating with) a system that uses rich claims, see the topics in
Authorization.
In This Section
Programming WCF SecurityAn overview of the programming model used to secure messages.
Transport Security OverviewAn overview of how to secure messages through the transport layer.
Message Security in WCFSummarizes reasons for using message-level security in Windows
Communication Foundation (WCF).
Secure SessionsA discussion of the considerations required when securing a WCF session.
Working with CertificatesAn explanation of some of the common tasks required when using X.509
certificates.
Reference
System.ServiceModel
System.ServiceModel.Channels
System.ServiceModel.Security
Related Sections
Security Concepts
Extending Security
Common Security Scenarios
Bindings and Security
Security Capabilities with Custom Bindings
Extending Security
Authorization
Authentication
The following topics show a number of different mechanisms in Windows Communication
Foundation (WCF) that provide authentication, for example, Windows authentication, X.509
certificates, and user name and passwords.
In This Section
How to: Use the ASP.NET Membership ProviderASP.NET features include a membership and role
provider, a database to store user name/password pairs for authentication, and user roles for
authorization. This topic explains how WCF services can use the same database to authenticate and
authorize users.
How to: Use a Custom User Name and Password ValidatorDemonstrates how to integrate a custom user
name/password validator.
Service Identity and AuthenticationAs an extra safeguard, a client can authenticate the service by
specifying the expected identity of the service. If the expected identity and the identity returned by the
service do not match, authentication fails.
Security Negotiation and TimeoutsDescribes how to use the NegotiationTimeout property in the
LocalServiceSecuritySettings class.
Resource Links for 70-513 WCF Certification Exam
287
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Debugging Windows Authentication ErrorsFocuses on common problems encountered when using
Windows authentication.
Reference
System.ServiceModel
Related Sections
Common Security Scenarios
Authorization
Authorization is the process of controlling access and rights to resources, such as services or
files. The topics in this section show you how to perform this basic task in Windows
Communication Foundation (WCF) in a variety of ways.
In This Section
Access Control MechanismsProvides a brief outline of the authorization mechanisms in WCF, and
suggested uses.
How to: Restrict Access with the PrincipalPermissionAttribute ClassShows the process of restricting
access to a service with the PrincipalPermissionAttribute.
How to: Use the ASP.NET Role Provider with a ServiceWalks through the configuration of a service to
enable it to use the role provider feature of ASP.NET.
How to: Use the ASP.NET Authorization Manager Role Provider with a ServiceASP.NET can use the
Authorization Manager to manage authorization for a Web site. WCF can similarly leverage the
ASP.NET/Authorization Manager combination for authorization of clients.
Managing Claims and Authorization with the Identity ModelExplains the basics of using the Identity
Model infrastructure for claims-based authorization.
Delegation and Impersonation with WCFExplains the difference between delegation and impersonation.
Reference
System.ServiceModel.Security
PrincipalPermissionMode
ServiceAuthorizationBehavior
PrincipalPermissionAttribute
Related Sections
Authentication
Federation
This topic provides a brief overview of the concept of federated security. It also describes
Windows Communication Foundation (WCF) support for deploying federated security
architectures. For a sample application that demonstrates federation, see Federation Sample.
Definition of Federated Security
Federated security allows for clean separation between the service a client is accessing and the
associated authentication and authorization procedures. Federated security also enables
collaboration across multiple systems, networks, and organizations in different trust realms.
Resource Links for 70-513 WCF Certification Exam
288
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
WCF provides support for building and deploying distributed systems that employ federated
security.
Elements of a Federated Security Architecture
The federated security architecture has three key elements, as described in the following table.
Element Description
Domain/realm
A single unit of security administration or trust. A typical domain might
include a single organization.
Federation
A collection of domains that have established trust. The level of trust may
vary, but typically includes authentication and almost always includes
authorization. A typical federation might include a number of organizations
that have established trust for shared access to a set of resources.
Security Token
Service (STS)
A Web service that issues security tokens; that is, it makes assertions based on
evidence that it trusts, to whomever trusts it. This forms the basis of trust
brokering between domains.
Example Scenario
The following illustration shows an example of federated security.

This scenario includes two organizations: A and B. Organization B has a Web resource (a Web
service) that some users in organization A find valuable.
Note:
This section uses the terms resource, service, and Web service interchangeably.
Typically, organization B requires that a user from organization A provide some valid form of
authentication before accessing the service. In addition, the organization may also require that
the user be authorized to access the specific resource in question. One way to address this
problem and enable users in organization A to access the resource in organization B is as
follows:
Users from organization A register their credentials (a user name and password) with organization B.
Resource Links for 70-513 WCF Certification Exam
289
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
During the resource access, users from organization A present their credentials to organization B and are
authenticated before accessing the resource.
This approach has three significant drawbacks:
Organization B has to manage the credentials for users from organization A in addition to managing the
credentials of its local users.
Users in organization A need to maintain an additional set of credentials (that is, remember an
additional user name and password) apart from the credentials they normally use to gain access to
resources within organization A. This usually encourages the practice of using the same user name and
password at multiple service sites, which is a weak security measure.
The architecture does not scale as more organizations perceive the resource at organization B as being
of some value.
An alternative approach, which addresses the previously mentioned drawbacks, is to employ
federated security. In this approach, organizations A and B establish a trust relationship and
employ Security Token Service (STS) to enable brokering of the established trust.
In a federated security architecture, users from organization A know that if they want to access
the Web service in organization B that they must present a valid security token from the STS at
organization B, which authenticates and authorizes their access to the specific service.
On contacting the STS B, the users receive another level of indirection from the policy
associated with the STS. They must present a valid security token from the STS A (that is, the
client trust realm) before the STS B can issue them a security token. This is a corollary of the
trust relationship established between the two organizations and implies that organization B does
not have to manage identities for users from organization A. In practice, STS B typically has a
null issuerAddress and issuerMetadataAddress. For more information, see How to: Configure
a Local Issuer. In that case, the client consults a local policy to locate STS A. This configuration
is called home realm federation and it scales better because STS B does not have to maintain
information about STS A.
The users then contact the STS at organization A and obtain a security token by presenting
authentication credentials that they normally use to gain access to any other resource within
organization A. This also alleviates the problem of users having to maintain multiple sets of
credentials or using the same set of credentials at multiple service sites.
Once the users obtain a security token from the STS A, they present the token to the STS B.
Organization B proceeds to perform authorization of the users' requests and issues a security
token to the users from its own set of security tokens. The users can then present their token to
the resource at organization B and access the service.
Support for Federated Security in WCF
WCF provides turnkey support for deploying federated security architectures through the
wsFederationHttpBinding element.
The wsFederationHttpBinding element element provides for a secure, reliable, interoperable
binding that entails the use of HTTP as the underlying transport mechanism for request-reply
communication style, employing text and XML as the wire format for encoding.
The use of wsFederationHttpBinding element in a federated security scenario can be decoupled
into two logically independent phases, as described in the following sections.
Phase 1: Design Phase
During the design phase, the client uses the ServiceModel Metadata Utility Tool (Svcutil.exe) to
read the policy the service endpoint exposes and to collect the service's authentication and
Resource Links for 70-513 WCF Certification Exam
290
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
authorization requirements. The appropriate proxies are constructed to create the following
federated security communication pattern at the client:
Obtain a security token from the STS in the client trust realm.
Present the token to the STS in the service trust realm.
Obtain a security token from the STS in the service trust realm.
Present the token to the service to access the service.
Phase 2: Run-Time Phase
During the run-time phase, the client instantiates an object of the WCF client class and makes a
call using the WCF client. The underlying framework of WCF handles the previously mentioned
steps in the federated security communication pattern and enables the client to seamlessly
consume the service.
Sample Implementation Using WCF
The following illustration shows a sample implementation for a federated security architecture
using native support from WCF.

Example MyService
The service MyService exposes a single endpoint through MyServiceEndpoint. The following
illustration shows the address, binding, and contract associated with the endpoint.
Resource Links for 70-513 WCF Certification Exam
291
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

The service endpoint MyServiceEndpoint uses the wsFederationHttpBinding element and
requires a valid Security Assertions Markup Language (SAML) token with an accessAuthorized
claim issued by STS B. This is declaratively specified in the service configuration.
<system.serviceModel>
<services>
<service type="FederationSample.MyService"
behaviorConfiguration='MyServiceBehavior'>
<endpoint address=""binding="
wsFederationHttpBinding"bindingConfiguration='MyServiceBinding'contract="Fede
ration.IMyService" />
</service>
</services>
<bindings>
<wsFederationHttpBinding>
<!-- This is the binding used by MyService. It redirects
clients to STS-B. -->
<binding name='MyServiceBinding'>
<security mode="Message">
<message issuedTokenType=
"http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<issuer address="http://localhost/FederationSample/STS-B/STS.svc" />
<issuerMetadata address="http://localhost/FederationSample/STS-B/STS.svc/mex"
/>
<requiredClaimTypes>
<add claimType="http://tempuri.org:accessAuthorized" />
</requiredClaimTypes>
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
<behaviors>
<behavior name='MyServiceBehavior'>
<serviceAuthorization
operationRequirementType="FederationSample.MyServiceOperationRequirement,
MyService" />
<serviceCredentials>
<serviceCertificate findValue="CN=FederationSample.com"
x509FindType="FindBySubjectDistinguishedName"storeLocation='LocalMachine'
storeName='My' />
</serviceCredentials>
</behavior>
</behaviors>
</system.serviceModel>
Note:
A subtle point should be noted about the claims required by MyService. The second figure indicates
Resource Links for 70-513 WCF Certification Exam
292
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
that MyService requires a SAML token with the accessAuthorized claim. To be more precise, this
specifies the claim type that MyService requires. The fully-qualified name of this claim type is
http://tempuri.org:accessAuthorized (along with the associated namespace), which is used in the service
configuration file. The value of this claim indicates the presence of this claim and is assumed to be set to
true by STS B.
At runtime, this policy is enforced by the MyServiceOperationRequirement class that is
implemented as part of the MyService.
VB
Imports System
Imports System.Collections.Generic
Imports System.IdentityModel.Claims
Imports System.IdentityModel.Policy
Imports System.IdentityModel.Tokens
Imports System.Security.Cryptography.X509Certificates
Imports System.Security.Permissions
Imports System.ServiceModel
Imports System.ServiceModel.Channels
Imports System.ServiceModel.Security.Tokens
Imports System.Text
...
PublicClass myServiceAuthorizationManageInherits ServiceAuthorizationManager
' Override the CheckAccess method to enforce access control
requirements.PublicOverloadsOverridesFunction CheckAccess(ByVal
operationContext As OperationContext) AsBoolean
Dim authContext = perationContext.ServiceSecurityContext.AuthorizationContext
If authContext.ClaimSets IsNothingThen
ReturnFalse
EndIf
If authContext.ClaimSets.Count<> 1 Then
ReturnFalse
EndIf
Dim myClaimSet = authContext.ClaimSets(0)
IfNot IssuedBySTS_B(myClaimSet) Then
ReturnFalse
EndIf
If myClaimSet.Count<> 1 Then
ReturnFalse
EndIf
Dim myClaim = myClaimSet(0)
If myClaim.ClaimType = "http://www.tmpuri.org:accessAuthorized"Then
Dim resource = TryCast(myClaim.Resource, String)
If resource IsNothingThen
ReturnFalse
EndIf
If resource <>"true"Then
ReturnFalse
EndIf
ReturnTrue
Else
ReturnFalse
EndIf
EndFunction
' This helper method checks whether SAML Token was issued by STS-B.
Resource Links for 70-513 WCF Certification Exam
293
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
' It compares the Thumbprint Claim of the Issuer against the
' Certificate of STS-B.
PrivateFunction IssuedBySTS_B(ByVal myClaimSet As ClaimSet) AsBoolean
Dim issuerClaimSet = myClaimSet.Issuer
If issuerClaimSet IsNothingThen
ReturnFalse
EndIf
If issuerClaimSet.Count<> 1 Then
ReturnFalse
EndIf
Dim issuerClaim = issuerClaimSet(0)
If issuerClaim.ClaimType <> ClaimTypes.Thumbprint Then
ReturnFalse
EndIf
If issuerClaim.Resource IsNothingThen
ReturnFalse
EndIf
Dim claimThumbprint() = CType(issuerClaim.Resource, Byte())
' It is assumed that stsB_Certificate is a variable of type
' X509Certificate2 that is initialized with the Certificate of
' STS-B.
Dim stsB_Certificate = GetStsBCertificate()
Dim certThumbprint() = stsB_Certificate.GetCertHash()
If claimThumbprint.Length <> certThumbprint.Length Then
ReturnFalse
EndIf
For i = 0 To claimThumbprint.Length - 1
If claimThumbprint(i) <> certThumbprint(i) Then
ReturnFalse
EndIf
Next i
ReturnTrue
EndFunction


STS B
The following illustration shows the STS B. As stated earlier, a security token service (STS) is
also a Web service and can have its associated endpoints, policy, and so on.

STS B exposes a single endpoint, called STSEndpoint that can be use to request security tokens.
Specifically, STS B issues SAML tokens with the accessAuthorized claim, which can be
presented at the MyService service site for accessing the service. However, STS B requires users
to present a valid SAML token issued by STS A that contains the userAuthenticated claim. This
is declaratively specified in the STS configuration.
<system.serviceModel>
<services>
<service type="FederationSample.STS_B" behaviorConfiguration=
"STS-B_Behavior">
Resource Links for 70-513 WCF Certification Exam
294
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<endpoint address=""binding="wsFederationHttpBinding"
bindingConfiguration='STS-B_Binding'contract="FederationSample.ISts" />
</service>
</services>
<bindings>
<wsFederationHttpBinding>
<!-- This is the binding used by STS-B. It redirects clients to
STS-A. -->
<binding name='STS-B_Binding'>
<security mode='Message'>
<message issuedTokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-
token-profile-1.1#SAMLV1.1">
<issuer address='http://localhost/FederationSample/STS-A/STS.svc' />
<issuerMetadata address='http://localhost/FederationSample/STS-
A/STS.svc/mex'/>
<requiredClaimTypes>
<add claimType='http://tempuri.org:userAuthenticated'/>
</requiredClaimTypes>
</message>
</security>
</binding>
</wsFederationHttpBinding>
</bindings>
<behaviors>
<behavior name='STS-B_Behavior'>
<serviceAuthorization
operationRequirementType='FederationSample.STS_B_OperationRequirement, STS_B'
/>
<serviceCredentials>
<serviceCertificate findValue='CN=FederationSample.com'
x509FindType='FindBySubjectDistinguishedName'storeLocation='LocalMachine'stor
eName='My' />
</serviceCredentials>
</behavior>
</behaviors>
</system.serviceModel>
Note:
Again, the userAuthenticated claim is the claim type that is required by STS B. The fully-qualified
name of this claim type is http://tempuri.org:userAuthenticated (along with the associated namespace),
which is used in the STS configuration file. The value of this claim indicates the presence of this claim
and is assumed to be set to true by STS A.
At runtime, the STS_B_OperationRequirement class enforces this policy, which is implemented
as part of STS B.
VB
PublicClass STS_B_AuthorizationManager
Inherits ServiceAuthorizationManager
' Override AccessCheck to enforce access control requirements.
PublicOverloadsOverridesFunction CheckAccess(ByVal operationContext As
OperationContext) AsBoolean
Dim authContext = perationContext.ServiceSecurityContext.AuthorizationContext
If authContext.ClaimSets IsNothingThen
ReturnFalse
Resource Links for 70-513 WCF Certification Exam
295
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
EndIf
If authContext.ClaimSets.Count<> 1 Then
ReturnFalse
EndIf
Dim myClaimSet = authContext.ClaimSets(0)
IfNot IssuedBySTS_A(myClaimSet) Then
ReturnFalse
EndIf
If myClaimSet.Count<> 1 Then
ReturnFalse
EndIf
Dim myClaim = myClaimSet(0)
If myClaim.ClaimType = "http://www.tmpuri.org:userAuthenticated"Then
Dim resource = TryCast(myClaim.Resource, String)
If resource IsNothingThen
ReturnFalse
EndIf
If resource <>"true"Then
ReturnFalse
EndIf
ReturnTrue
Else
ReturnFalse
EndIf
EndFunction
' This helper method checks whether SAML Token was issued by STS-A.
' It compares the Thumbprint Claim of the Issuer against the
' Certificate of STS-A.
PrivateFunction IssuedBySTS_A(ByVal myClaimSet As ClaimSet) AsBoolean
Dim issuerClaimSet = myClaimSet.Issuer
If issuerClaimSet IsNothingThen
ReturnFalse
EndIf
If issuerClaimSet.Count<> 1 Then
ReturnFalse
EndIf
Dim issuerClaim = issuerClaimSet(0)
If issuerClaim.ClaimType <> ClaimTypes.Thumbprint Then
ReturnFalse
EndIf
If issuerClaim.Resource IsNothingThen
ReturnFalse
EndIf
Dim claimThumbprint() = CType(issuerClaim.Resource, Byte())
' It is assumed that stsA_Certificate is a variable of type X509Certificate2
' that is initialized with the Certificate of STS-A.
Dim stsA_Certificate = GetStsACertificate()

Dim certThumbprint() = stsA_Certificate.GetCertHash()
If claimThumbprint.Length <> certThumbprint.Length Then
ReturnFalse
EndIf
For i = 0 To claimThumbprint.Length - 1
If claimThumbprint(i) <> certThumbprint(i) Then
ReturnFalse
EndIf
Resource Links for 70-513 WCF Certification Exam
296
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Next i
ReturnTrue
EndFunction
If the access check is clear, STS B issues a SAML token with the accessAuthorized claim.
VB
' Create the list of SAML Attributes.
Dim samlAttributes AsNew List(Of SamlAttribute)()
' Add the accessAuthorized claim.
Dim strList AsNew List(Of String)()
strList.Add("true")
samlAttributes.Add(New
SamlAttribute("http://www.tmpuri.org","accessAuthorized", strList))
' Create the SAML token with the accessAuthorized claim. It is assumed that
' the method CreateSamlToken() is implemented as part of STS-B.
Dim samlToken = CreateSamlToken(proofToken, _issuerToken, _samlConditions,
_samlSubjectNameFormat, _samlSubjectEmailAddress, _samlAttributes)
STS A
The following illustration shows the STS A.

Similar to the STS B, the STS A is also a Web service that issues security tokens and exposes a
single endpoint for this purpose. However, it uses a different binding (wsHttpBinding) and
requires users to present a valid CardSpace with an emailAddress claim. In response, it issues
SAML tokens with the userAuthenticated claim. This is declaratively specified in the service
configuration.
<system.serviceModel>
<services>
<service type="FederationSample.STS_A" behaviorConfiguration="STS-
A_Behavior">
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="STS-A_Binding"contract="FederationSample.ISts">
<identity>
<certificateReference findValue="CN=FederationSample.com"
x509FindType="FindBySubjectDistinguishedName"storeLocation="LocalMachine"
storeName="My" />
</identity>
<endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<!-- This is the binding used by STS-A. It requires users to present
a CardSpace. -->
<binding name='STS-A_Binding'>
<security mode='Message'>
<message clientCredentialType="CardSpace" />
</security>
</binding>
</wsHttpBinding>
Resource Links for 70-513 WCF Certification Exam
297
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
</bindings>
<behaviors>
<behavior name='STS-A_Behavior'>
<serviceAuthorization operationRequirementType=
"FederationSample.STS_A_OperationRequirement, STS_A" />
<serviceCredentials>
<serviceCertificate findValue="CN=FederationSample.com"
x509FindType='FindBySubjectDistinguishedName'storeLocation='LocalMachine'
storeName='My' />
</serviceCredentials>
</behavior>
</behaviors>
</system.serviceModel>
At runtime, the STS_A_OperationRequirement class enforces this policy, which is implemented
as part of STS A.
VB
PublicClass STS_A_AuthorizationManagerInherits ServiceAuthorizationManager
' Override AccessCheck to enforce access control requirements.
PublicOverloadsOverridesFunction CheckAccess(ByVal operationContext As
OperationContext) AsBoolean
Dim authContext =operationContext.ServiceSecurityContext.AuthorizationContext
If authContext.ClaimSets IsNothingThen
ReturnFalse
EndIf
If authContext.ClaimSets.Count<> 1 Then
ReturnFalse
EndIf
Dim myClaimSet = authContext.ClaimSets(0)
If myClaimSet.Count<> 1 Then
ReturnFalse
EndIf
Dim myClaim = myClaimSet(0)
If myClaim.ClaimType =
"http://schemas.microsoft.com/ws/2005/05/identity/claims:EmailAddress"AndAlso
myClaim.Right = Rights.PossessProperty Then
Dim emailAddress = TryCast(myClaim.Resource, String)
If emailAddress IsNothingThen
ReturnFalse
EndIf
IfNot IsValidEmailAddress(emailAddress) Then
ReturnFalse
EndIf
ReturnTrue
Else
ReturnFalse
EndIf
EndFunction
' This helper method performs a rudimentary check for whether
'a given e-mail is valid.
PrivateSharedFunction IsValidEmailAddress(ByVal emailAddress AsString)
AsBoolean
Dim splitEmail() = emailAddress.Split("@"c)
If splitEmail.Length <> 2 Then
ReturnFalse
EndIf
Resource Links for 70-513 WCF Certification Exam
298
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
IfNot splitEmail(1).Contains(".") Then
ReturnFalse
EndIf
ReturnTrue
EndFunction
EndClass
If the access is true, STS A issues a SAML token with userAuthenticated claim.
VB
' Create the list of SAML Attributes.
Dim samlAttributes AsNew List(Of SamlAttribute)()
' Add the userAuthenticated claim.
Dim strList AsNew List(Of String)()
strList.Add("true")
Dim mySamlAttribute AsNew SamlAttribute("http://www.tmpuri.org",
_"userAuthenticated", _ strList)
samlAttributes.Add(mySamlAttribute)
' Create the SAML token with the userAuthenticated claim. It is assumed that
' the method CreateSamlToken() is implemented as part of STS-A.
Dim samlToken = CreateSamlToken(proofToken, issuerToken, samlConditions, _
samlSubjectNameFormat, _
samlSubjectEmailAddress, _
samlAttributes)

Client at Organization A
The following illustration shows the client at organization A, along with the steps involved in
making a MyService service call. The other functional components are also included for
completeness.

Summary
Federated security provides a clean division of responsibility and helps to build secure, scalable
service architectures. As a platform for building and deploying distributed applications, WCF
provides native support for implementing federated security.
Federation and Trust
Resource Links for 70-513 WCF Certification Exam
299
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
This topic covers various aspects related to federated applications, trust boundaries and
configuration, and use of issued tokens in Windows Communication Foundation (WCF).
Services, Security Token Services, and Trust
Services that expose federated endpoints typically expect clients to authenticate using a token
provided by a specific issuer. It is important that the service is configured with the correct
credentials for the issuer; otherwise, it will not be able to verify signatures over the issued
tokens, and the client will be unable to communicate with the service. For more information
about configuring issuer credentials on the service, see How to: Configure Credentials on a
Federation Service.
Similarly, when using symmetric keys, the keys are encrypted for the target service, so you must
configure the security token service with the correct credentials for the target service; otherwise,
it will be unable to encrypt the key for the target service, and again, the client will be unable to
communicate with the service.
WCF services use the value of the MaxClockSkew property on the SecurityBindingElement to
allow for clock skew between the client and service. In federation, the MaxClockSkew setting
applies to clock skews between both the client and the security token service from where the
client obtained the issued token. Therefore, security token services need not make clock-skew
allowances when setting the issued token's effective and expiration times.
Note:
The importance of clock skew increases as the lifetime of the issued token shortens. In most cases, clock
skew is not a significant issue if the token lifetime is 30 minutes or more. Scenarios with shorter
lifetimes or where the exact validity time of the token is important should be designed to take clock
skew into account.
Federated Endpoints and Time-Outs
When a client communicates with a federated endpoint, it must first acquire an appropriate token
from a security token service. If the security token service exposes a federated endpoint, the
client must first obtain a token from the issuer for that endpoint. Each token acquisition takes
time, and that time is subject to the overall time-out for sending the actual message to the final
endpoint.
For example, the time-out on the client-side channel is set to 30 seconds. Two token issuers need
to be called to retrieve tokens before sending the message to the final endpoint, and each takes 15
seconds to issue a token. In this case, the attempt will fail and a TimeoutException is thrown.
Thus, you need to set the OperationTimeout value on the client channel to a value large enough
to include the time taken to retrieve all issued tokens. In the case where a value is not specified
for the OperationTimeout property, the OpenTimeout property or the SendTimeout property (or
both) need to be set to a value large enough to include the time taken to retrieve all issued tokens.
Token Lifetime and Renewal
WCF clients do not check the issued token when making an initial request to a service. Rather,
WCF trusts the security token service to issue a token with appropriate effective and expiration
times. If the token is cached by the client and reused, the token lifetime is checked on subsequent
requests and the client automatically renews the token if necessary. For more information about
token caching, see How to: Create a Federated Client.
Resource Links for 70-513 WCF Certification Exam
300
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Specifying short lifetimes, on the order of 30 seconds or less for issued tokens or security context
tokens, may result in negotiation time-outs or other exceptions being thrown by WCF clients
when requesting issued tokens or when negotiating or renewing security context tokens.
Issued Tokens and InclusionMode
Whether an issued token is serialized in a message sent from a client to a federated endpoint or
not is controlled by setting the InclusionMode property of the SecurityTokenParameters class.
This property can be set to one of the SecurityTokenInclusionMode enumeration values, but it is
not useful in most federated scenarios. The SecurityTokenInclusionMode.Never and
SecurityTokenInclusionMode.AlwaysToInitiator values cause the client to send a reference to
the token issued by the security token service to the relying party. Unless the relying party
possesses a copy of the issued token, authentication will fail because the token reference is not
resolvable. WCF treats SecurityTokenInclusionMode.Once as equivalent to
SecurityTokenInclusionMode.AlwaysToRecipient.
Partial Trust
Starting with the .NET Framework version 3.5, partially trusted callers can access public types
and methods implemented in System.ServiceModel, System.Runtime.Serialization, and
System.ServiceModel.Web. This section describes supported scenarios for using Windows
Communication Foundation (WCF) within a partially trusted application as well as the limited
subset of WCF functionality available to applications running with reduced code access security
(CAS) permissions.
Best Practices for Security in WCF
The following sections list the best practices to consider when creating secure applications using
Windows Communication Foundation (WCF). For more information about security, see Security
Considerations, Security Considerations for Data, and Security Considerations with Metadata.
Identify Services Performing Windows Authentication with
SPNs
Services can be identified with either user principal names (UPNs) or service principal names
(SPNs). Services running under machine accounts such as network service have an SPN identity
corresponding to the machine they're running. Services running under user accounts have a UPN
identity corresponding to the user they're running as, although the setspn tool can be used to
assign an SPN to the user account. Configuring a service so it can be identified via SPN and
configuring the clients connecting to the service to use that SPN can make certain attacks more
difficult. This guidance applies to bindings using Kerberos or SSPI negotiation. Clients should
still specify an SPN in the case where SSPI falls back to NTLM.
Verify Service Identities in WSDL
WS-SecurityPolicy allows services to publish information about their own identities in metadata.
When retrieved via svcutil or other methods such as WsdlImporter, this identity information is
translated to the identity properties of the WCF service endpoint addresses. Clients which do not
verify that these service identities are correct and valid effectively bypass service authentication.
A malicious service can exploit such clients to execute credential forwarding and other "man in
the middle" attacks by changing the identity claimed in its WSDL.
Resource Links for 70-513 WCF Certification Exam
301
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Use X509 Certificates Instead of NTLM
WCF offers two mechanisms for peer-to-peer authentication: X509 certificates (used by peer
channel) and Windows authentication where an SSPI negotiation downgrades from Kerberos to
NTLM. Certificate-based authentication using key sizes of 1024 bits or more is preferred to
NTLM for several reasons:
the availability of mutual authentication,
the use of stronger cryptographic algorithms, and
the greater difficulty of utilizing forwarded X509 credentials.
For an overview of NTLM forwarding attacks, go to
http://msdn.microsoft.com/msdnmag/issues/06/09/SecureByDesign/default.aspx .
Always Revert After Impersonation
When using APIs that enable impersonation of a client, be sure to revert to the original identity.
For example, when using the WindowsIdentity and WindowsImpersonationContext, use the C#
using statement or the Visual Basic Using statement, as shown in the following code. The
WindowsImpersonationContext class implements the IDisposable interface, and therefore the
common language runtime (CLR) automatically reverts to the original identity once the code
leaves the using block.
C#
VB
WindowsIdentity identity = ServiceSecurityContext.Current.WindowsIdentity;
using (identity.Impersonate())
{
// Run code under the caller's identity.
}

Impersonate Only as Needed
Using the Impersonate method of the WindowsIdentity class, it is possible to use impersonation
in a very controlled scope. This is in contrast to using the Impersonation property of the
OperationBehaviorAttribute, which allows impersonation for the scope of the entire operation.
Whenever possible, control the scope of impersonation by using the more precise Impersonate
method.
Obtain Metadata from Trusted Sources
Be sure you trust the source of your metadata and make sure that no one has tampered with the
metadata. Metadata retrieved using the HTTP protocol is sent in clear text and can be tampered
with. If the service uses the HttpsGetEnabled and HttpsGetUrl properties, use the URL supplied
by the service creator to download the data using the HTTPS protocol.
Publish Metadata Using Security
To prevent tampering with a service's published metadata, secure the metadata exchange
endpoint with transport or message-level security. For more information, see Publishing
Metadata Endpoints and How to: Publish Metadata for a Service Using Code.
Ensure Use of Local Issuer
If an issuer address and binding are specified for a given binding, the local issuer is not used for
endpoints that use that binding. Clients who expect to always use the local issuer should ensure
Resource Links for 70-513 WCF Certification Exam
302
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
that they do not use such a binding or that they modify the binding such that the issuer address is
null.
SAML Token Size Quotas
When Security Assertions Markup Language (SAML) tokens are serialized in messages, either
when they are issued by a Security Token Service (STS) or when clients present them to services
as part of authentication, the maximum message size quota must be sufficiently large to
accommodate the SAML token and the other message parts. In normal cases, the default message
size quotas are sufficient. However, in cases where a SAML token is large because it contains
hundreds of claims, the quotas should be increased to accommodate the serialized token. For
more information about quotas, see Security Considerations for Data.
Set SecurityBindingElement.IncludeTimestamp to True on
Custom Bindings
When you create a custom binding, you must set IncludeTimestamp to true. Otherwise, if
IncludeTimestamp is set to false, and the client is using an asymmetric key-based token such as
an X509 certificate, the message will not be signed.
Performance Considerations
Performance considerations are always important when building applications. This section
contains entries related to performance and security.

Configure secure Bindings.This objective may include but is not limited to: transport, message,
mixed mode

Configure message security.This objective may include but is not limited to: specifying
protection levels on different message parts
Message Security in WCF
Windows Communication Foundation (WCF) has two major modes for providing security
(Transport and Message) and a third mode (TransportWithMessageCredential) that
combines the two. This topic discusses message security and the reasons to use it.
What Is Message Security?
Message security uses the WS-Security specification to secure messages. The specification
describes enhancements to SOAP messaging to ensure confidentiality, integrity, and
authentication at the SOAP message level (instead of the transport level).
In brief, message security differs from transport security by encapsulating the security
credentials and claims with every message along with any message protection (signing or
encryption). Applying the security directly to the message by modifying its content allows the
secured message to be self-containing with respect to the security aspects. This enables some
scenarios that are not possible when transport security is used.
Reasons to Use Message Security
In message-level security, all of the security information is encapsulated in the message.
Securing the message with message-level security instead of transport-level security has the
following advantages:
Resource Links for 70-513 WCF Certification Exam
303
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
End-to-end security. A secure transport, such as Secure Sockets Layer (SSL) works only when the
communication is point-to-point. If the message is routed to one or more SOAP intermediaries before
reaching the ultimate receiver, the message itself is not protected once an intermediary reads it from
the wire. Additionally, the client authentication information is available only to the first intermediary
and must be transmitted to the ultimate received in out-of-band fashion, if necessary. This applies even
if the entire route uses SSL security between individual hops. Because message security works directly
with the message and secures the XML in it, the security stays with the message regardless of how many
intermediaries are involved with the message before it reaches the ultimate receiver. This enables true
end-to-end security scenario.
Increased flexibility. Parts of the message, instead of the entire message, can be signed or encrypted.
This means that intermediaries can view the parts of the message that are intended for them. If the
sender needs to make part of the information in the message visible to the intermediaries but wants to
ensure that it is not tampered with, it can just sign it but leave it unencrypted. Since the signature is part
of the message, the ultimate receiver can verify that the information in the message was received intact.
One scenario might have a SOAP intermediary service that routes message according the Action header
value. By default, WCF does not encrypt the Action value but signs it if message security is used.
Therefore, this information is available to all intermediaries, but no one can change it.
Support for multiple transports. You can send secured messages over many different transports, such as
named pipes and TCP, without having to rely on the protocol for security. With transport-level security,
all the security information is scoped to a single particular transport connection and is not available from
the message content itself. Message security makes the message secure regardless of what transport
you use to transmit the message, and the security context is directly embedded inside the message.
Support for a wide set of credentials and claims. The message security is based on the WS-Security
specification, which provides an extensible framework capable of transmitting any type of claim inside
the SOAP message. Unlike transport security, the set of authentication mechanisms, or claims, that you
can use is not limited by the transport capabilities. WCF message security includes multiple types of
authentication and claim transmission and can be extended to support additional types as necessary.
For those reasons, for example, a federated credentials scenario is not possible without message
security. For more information about federation scenarios WCF supports, see Federation and Issued
Tokens.
How Message and Transport Security Compare
Pros and Cons of Transport-Level Security
Transport security has the following advantages:
Does not require that the communicating parties understand XML-level security concepts. This can
improve the interoperability, for example, when HTTPS is used to secure the communication.
Generally improved performance.
Hardware accelerators are available.
Streaming is possible.
Transport security has the following disadvantages:
Hop-to-hop only.
Limited and inextensible set of credentials.
Transport-dependent.
Disadvantages of Message-Level Security
Message security has the following disadvantages:
Performance
Cannot use message streaming.
Resource Links for 70-513 WCF Certification Exam
304
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Requires implementation of XML-level security mechanisms and support for WS-Security specification.
This might affect the interoperability.

Implement Authentication.This objective may include but is not limited to: Microsoft ASP.NET
Membership Provider, Custom Provider, Windows Integrated Security, certificates (X.509),
Federated Authentication endpoint identity; configuring client credentials; Custom ValidatorThis
objective does not include: Geneva Framework
How to: Use the ASP.NET Membership
Provider
The ASP.NET membership provider is a feature that enables ASP.NET developers to create Web
sites that allow users to create unique user name and password combinations. With this facility,
any user can establish an account with the site, and sign in for exclusive access to the site and its
services. This is in contrast to Windows security, which requires users to have accounts in a
Windows domain. Instead, any user that supplies his or her credentials (the user name/password
combination) can use the site and its services.
For a sample application, see Membership and Role Provider. For information about using the
ASP.NET role provider feature, see How to: Use the ASP.NET Role Provider with a Service.
The membership feature requires using a SQL Server database to store the user information. The
feature also includes methods for prompting with a question any users who have forgotten their
password.
Windows Communication Foundation (WCF) developers can take advantage of these features
for security purposes. When integrated into an WCF application, users must supply a user
name/password combination to the WCF client application. To transfer the data to the WCF
service, use a binding that supports user name/password credentials, such as the WSHttpBinding
(in configuration, the wsHttpBinding Element) and set the client credential type to UserName.
On the service, WCF security authenticates the user based on the user name and password, and
also assigns the role specified by the ASP.NET role.
Note:
WCF does not provide methods to populate the database with user name/password combinations
or other user information.
To configure the membership provider
1. In the Web.config file, under the <system.web> element, create a <membership> element.
2. Under the <membership> element, create a <providers> element.
3. As a child to the <providers> element, add a <clear /> element to flush the collection of
providers.
4. Under the <clear /> element, create an <add> element with the following attributes set to
appropriate values: name, type, connectionStringName, applicationName,
enablePasswordRetrieval, enablePasswordReset, requiresQuestionAndAnswer,
requiresUniqueEmail, and passwordFormat. The name attribute is used later as a value in the
configuration file. The following example sets it to SqlMembershipProvider.
The following example shows the configuration section.
<!-- Configure the Sql Membership Provider -->
Resource Links for 70-513 WCF Certification Exam
305
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<membership defaultProvider="SqlMembershipProvider"
userIsOnlineTimeWindow="15">
<providers>
<clear />
<add
name="SqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="SqlConn"
applicationName="MembershipAndRoleProviderSample"
enablePasswordRetrieval="false"
enablePasswordReset="false"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="true"
passwordFormat="Hashed" />
</providers>
</membership>
To configure service security to accept the user
name/password combination
1. In the configuration file, under the <system.ServiceModel> element, add a <bindings> element.
2. Add a wsHttpBinding Element to the bindings section. For more information about creating an
WCF binding element, see How to: Specify a Service Binding in Configuration.
3. Set the mode attribute of the <security> element to Message.
4. Set the clientCredentialType attribute of the <message> element to UserName. This specifies
that a user name/password pair will be used as the client's credential.
The following example shows the configuration code for the binding.
<system.serviceModel>
<bindings>
<wsHttpBinding>
<!-- Set up a binding that uses UserName as the client credential type -->
<binding name="MembershipBinding">
<security mode ="Message">
<message clientCredentialType ="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
To configure a service to use the membership provider
1. As a child to the <system.serviceModel> element, add a <behaviors> element
2. Add a serviceBehaviors section to the <behaviors> element.
3. Add a Behavior element and set the name attribute to an appropriate value.
4. Add a <serviceCredentials> Element to the <behavior> element.
5. Add a userNameAuthentication element to the <serviceCredentials> element.
6. Set the userNamePasswordValidationMode attribute to MembershipProvider.
Note:
If the userNamePasswordValidationMode value is not set, WCF uses Windows
authentication instead of the ASP.NET membership provider.
Resource Links for 70-513 WCF Certification Exam
306
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
7. Set the membershipProviderName attribute to the name of the provider (specified when adding
the provider in the first procedure in this topic). The following example shows the
<serviceCredentials> fragment to this point.
8. <serviceCredentials>
9. <userNameAuthentication userNamePasswordValidationMode ="MembershipProvider"
10. membershipProviderName ="SqlMembershipProvider"/>
11. </serviceCredentials>
How to: Use a Custom User Name and
Password Validator
By default, when a user name and password is used for authentication, Windows Communication
Foundation (WCF) uses Windows to validate the user name and password. However, WCF
allows for custom user name and password authentication schemes, also known as validators. To
incorporate a custom user name and password validator, create a class that derives from
UserNamePasswordValidator and then configure it.
For a sample application, see UserNamePassword Validator.
To create a custom user name and password validator
1. Create a class that derives from UserNamePasswordValidator.
C#
VB

publicclass CustomUserNameValidator : UserNamePasswordValidator
{

2. Implement the custom authentication scheme by overriding the Validate method.
Do not use the code in the following example that overrides the Validate method in a production
environment. Replace the code with your custom user name and password validation scheme,
which might involve retrieving user name and password pairs from a database.
To return authentication errors back to the client, throw a FaultException in the Validate
method.
C#
VB
// This method validates users. It allows in two users, test1 and test2
// with passwords 1tset and 2tset respectively.
// This code is for illustration purposes only and
// must not be used in a production environment because it is not secure.
publicoverridevoid Validate(string userName, string password)
{
if (null == userName || null == password)
{
thrownew ArgumentNullException();
}

if (!(userName == "test1"&& password == "1tset") && !(userName == "test2"&&
password == "2tset"))
{
// This throws an informative fault to the client.
thrownew FaultException("Unknown Username or Incorrect Password");
// When you do not want to throw an infomative fault to the client,
Resource Links for 70-513 WCF Certification Exam
307
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
// throw the following exception.
// throw new SecurityTokenException("Unknown Username or Incorrect
Password");
}
}

To configure a service to use a custom user name and
password validator
1. Configure a binding that uses message security over any transport or transport-level security over
HTTP(S).
When using message security, add one of the system-provided bindings, such as wsHttpBinding
Element, or a customBinding Element that supports message security and the UserName
credential type.
When using transport-level security over HTTP(S), add either the wsHttpBinding Element or
<basicHttpBinding>, or a customBinding Element that uses HTTP(S) and the Basic
authentication scheme.
Note:
When .NET Framework version 3.5 or later is used, you can use a custom username and
password validator with message and transport security. With .NET Framework 3.0, a
custom username and password validator can only be used with message security.
1. In the configuration file, under the <system.ServiceModel> element, add a <bindings> element.
2. Add a wsHttpBinding Element or <basicHttpBinding> element to the bindings section. For more
information about creating an WCF binding element, see How to: Specify a Service Binding in
Configuration.
3. Set the mode attribute of the security element of wsHttpBinding or <security> of
<basicHttpBinding> to Message, Transport, orTransportWithMessageCredential.
4. Set the clientCredentialType attribute of the message element of wsHttpBinding or <transport>
of <wsHttpBinding>.

When using message security, set the clientCredentialType attribute of the message element of
wsHttpBinding to UserName.

When using transport-level security over HTTP(S), set the clientCredentialType attribute of the
<transport> of <wsHttpBinding> or <transport> of <basicHttpBinding> to Basic.
Note:
When a WCF service is hosted in Internet Information Services (IIS) using
transport-level security and the UserNamePasswordValidationMode property is
set to Custom, the custom authentication scheme uses a subset of Windows
authentication. That is because in this scenario, IIS performs Windows
authentication prior to WCF invoking the custom authenticator.
For more information about creating an WCF binding element, see How to: Specify a Service
Binding in Configuration.
The following example shows the configuration code for the binding.
<system.serviceModel>
<bindings>
Resource Links for 70-513 WCF Certification Exam
308
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<wsHttpBinding>
<binding name="Binding1">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
2. Configure a behavior that specifies that a custom user name and password validator is used to
validate user name and password pairs for incoming UserNameSecurityToken security tokens.
1. As a child to the <system.serviceModel> element, add a <behaviors> element.
2. Add a serviceBehaviors section to the <behaviors> element.
3. Add a <behavior> element and set the name attribute to an appropriate value.
4. Add a <serviceCredentials> Element to the <behavior> element.
5. Add a userNameAuthentication element to the <serviceCredentials> Element.
6. Set the userNamePasswordValidationMode to Custom.
Note:
If the userNamePasswordValidationMode value is not set, WCF uses Windows
authentication instead of the custom user name and password validator.
7. Set the customUserNamePasswordValidatorType to the type that represents your custom user
name and password validator.
The following example shows the <serviceCredentials> fragment to this point.
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.Calculato
rService.CustomUserNameValidator, service" />
</serviceCredentials>
Example
The following code example demonstrates how to create a custom user name and password
validator. Do not use the code that overrides the Validate method in a production environment.
Replace the code with your custom user name and password validation scheme, which might
involve retrieving user name and password pairs from a database.
C#
VB
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;

using System.Security.Principal;

using System.ServiceModel;



...



publicclass CustomUserNameValidator : UserNamePasswordValidator
Resource Links for 70-513 WCF Certification Exam
309
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
{
// This method validates users. It allows in two users, test1 and test2
// with passwords 1tset and 2tset respectively.
// This code is for illustration purposes only and
// must not be used in a production environment because it is not secure.
publicoverridevoid Validate(string userName, string password)
{
if (null == userName || null == password)
{
thrownew ArgumentNullException();
}

if (!(userName == "test1"&& password == "1tset") && !(userName == "test2"&&
password == "2tset"))
{
// This throws an informative fault to the client.
thrownew FaultException("Unknown Username or Incorrect Password");
// When you do not want to throw an infomative fault to the client,
// throw the following exception.
// throw new SecurityTokenException("Unknown Username or Incorrect
Password");
}
}
}

Service Identity and Authentication
A service's endpoint identity is a value generated from the service Web Services Description
Language (WSDL). This value, propagated to any client, is used to authenticate the service.
After the client initiates a communication to an endpoint and the service authenticates itself to
the client, the client compares the endpoint identity value with the actual value the endpoint
authentication process returned. If they match, the client is assured it has contacted the expected
service endpoint. This functions as a protection against phishing by preventing a client from
being redirected to an endpoint hosted by a malicious service.
For a sample application that demonstrates identity setting, see Service Identity Sample. For
more information about endpoints and endpoint addresses, see Endpoint Addresses.
Note:
When you use NT LanMan (NTLM) for authentication, the service identity is not checked because, under
NTLM, the client is unable to authenticate the server. NTLM is used when computers are part of a
Windows workgroup, or when running an older version of Windows that does not support Kerberos
authentication.
When the client initiates a secure channel to send a message to a service over it, the Windows
Communication Foundation (WCF) infrastructure authenticates the service, and only sends the
message if the service identity matches the identity specified in the endpoint address the client
uses.
Identity processing consists of the following stages:
At design time, the client developer determines the service's identity from the endpoint's metadata
(exposed through WSDL).
Resource Links for 70-513 WCF Certification Exam
310
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
At runtime, the client application checks the claims of the service's security credentials before sending
any messages to the service.
Identity processing on the client is analogous to client authentication on the service. A secure
service does not execute code until the client's credentials have been authenticated. Likewise, the
client does not send messages to the service until the service's credentials have been
authenticated based on what is known in advance from the service's metadata.
The Identity property of the EndpointAddress class represents the identity of the service called
by the client. The service publishes the Identity in its metadata. When the client developer runs
the Service Model Metadata Utility Tool (Svcutil.exe) against the service endpoint, the generated
configuration contains the value of the service's Identity property. The WCF infrastructure (if
configured with security) verifies that the service possesses the identity specified.
Note:
The metadata contains the expected identity of the service, so it is recommended that you expose the
service metadata through secure means, for example, by creating an HTTPS endpoint for the service. For
more information, see How to: Secure Metadata Endpoints.
Identity Types
A service can provide five types of identities. Each identity type corresponds to an element that
can be contained inside the <identity> element in configuration. The type used depends on the
scenario and the service's security requirements. The following table describes each identity type.
Identity type Description Typical scenario
Domain Name System (DNS)
Use this element with
X.509 certificates or
Windows accounts. It
compares the DNS name
specified in the credential
with the value specified in
this element.
A DNS check enables you to use
certificates with DNS or subject
names. If a certificate is reissued
with the same DNS or subject
name, then the identity check is
still valid. When a certificate is
reissued, it gets a new RSA key
but retains the same DNS or
subject name. This means that
clients do not have to update their
identity information about the
service.
Certificate. The default when
ClientCredentialType is set to
Certificate.
This element specifies a
Base64-encoded X.509
certificate value to
compare with the client.
Also use this element
when using a CardSpace
as a credential to
authenticate the service.
This element restricts
authentication to a single
certificate based upon its
thumbprint value. This enables
stricter authentication because
thumbprint values are unique.
This comes with one caveat: If
the certificate is reissued with the
same Subject name, it also has a
new Thumbprint. Therefore,
clients are not able to validate the
Resource Links for 70-513 WCF Certification Exam
311
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
service unless the new
thumbprint is known. For more
information about finding a
certificate's thumbprint, see How
to: Retrieve the Thumbprint of a
Certificate.
Certificate Reference
Identical to the Certificate
option described
previously. However, this
element enables you to
specify a certificate name
and store location from
which to retrieve the
certificate.
Same as the Certificate scenario
described previously.
The benefit is that the certificate
store location can change.
RSA
This element specifies an
RSA key value to compare
with the client. This is
similar to the certificate
option but rather than
using the certificate's
thumbprint, the
certificate's RSA key is
used instead.
An RSA check enables you to
specifically restrict authentication
to a single certificate based upon
its RSA key. This enables stricter
authentication of a specific RSA
key at the expense of the service,
which no longer works with
existing clients if the RSA key
value changes.
User principal name (UPN). The
default when the
ClientCredentialType is set to
Windows and the service process
is not running under one of the
system accounts.
This element specifies the
UPN that the service is
running under. See the
Kerberos Protocol and
Identity section of
Overriding the Identity of
a Service for
Authentication.
This ensures that the service is
running under a specific
Windows user account. The user
account can be either the current
logged-on user or the service
running under a particular user
account.
This setting takes advantage of
Windows Kerberos security if the
service is running under a domain
account within an Active
Directory environment.
Service principal name (SPN). The
default when the
ClientCredentialType is set to
Windows and the service process
is running under one of the system
accountsLocalService,
LocalSystem, or NetworkService.
This element specifies the
SPN associated with the
service's account. See the
Kerberos Protocol and
Identity section of
Overriding the Identity of
a Service for
Authentication.
This ensures that the SPN and the
specific Windows account
associated with the SPN identify
the service.
You can use the Setspn.exe tool
to associate a machine account
for the service's user account.
This setting takes advantage of
Windows Kerberos security if the
Resource Links for 70-513 WCF Certification Exam
312
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
service is running under one of
the system accounts or under a
domain account that has an
associated SPN name with it and
the computer is a member of a
domain within an Active
Directory environment.
Specifying Identity at the Service
Typically, you do not have to set the identity on a service because the selection of a client
credential type dictates the type of identity exposed in the service metadata. For more
information about how to override or specify service identity, see Overriding the Identity of a
Service for Authentication.
Using the <identity> Element in Configuration
If you change the client credential type in the binding previously shown to Certificate, then the
generated WSDL contains a Base64 serialized X.509 certificate for the identity value as shown
in the following code. This is the default for all client credential types other than Windows.
XML
<Identityxmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
<KeyInfoxmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>MIIBxjCCAXSgAwIBAgIQmXJgyu9tro1M98GifjtuoDAJBgUrDgMCHQUAMBYx
FDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTA2MDUxNzIxNDQyNVoXDTM5MTIzMTIzNTk1OVowKTEQM
A4GA1UEChMHQ29udG9zbzEVMBMGA1UEAxMMaWRlbnRpdHkuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4
GNADCBiQKBgQDBmivcb8hYbh11hqVoDuB7zmJ2y230f/b4e+4P6yXtKKuhUdYcIqc8mAforIM4WWJ
EVGeJVq9sFEwqrL5Ryid8jMTRwPLvA/x/wvj1gtD1GWJ+aUh2pqieiGL7MWTepHAQBIibUxgOrAOz
0j9Xhg0iDFYScdYUjeqI3yZIDC7WbwIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcF
mRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwCQYFKw4DAh0FAA
NBADB/J2QjdSPL8Doj3pAveCXd/5fY03eo9kUym/Tmb4ubdqsObri0qnYR/n8Wxsa1yJ4Dks6cNBT
PS4l5B7zUeNo=</X509Certificate>
</X509Data>
</KeyInfo>
</Identity>

You can change the value of the default service identity or change the type of the identity by
using the <identity> element in configuration or by setting the identity in code. The following
configuration code sets a domain name system (DNS) identity with the value contoso.com.
Setting Identity Programmatically
Your service does not have to explicitly specify an identity, because WCF automatically
determines it. However, WCF allows you to specify an identity on an endpoint, if required. The
following code adds a new service endpoint with a specific DNS identity.
C#
VB
ServiceEndpoint ep = myServiceHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
String.Empty);
Resource Links for 70-513 WCF Certification Exam
313
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
EndpointAddress myEndpointAdd = new EndpointAddress(new
Uri("http://localhost:8088/calc"),
EndpointIdentity.CreateDnsIdentity("contoso.com"));
ep.Address = myEndpointAdd;

Specifying Identity at the Client
At design time, a client developer typically uses the ServiceModel Metadata Utility Tool
(Svcutil.exe) to generate client configuration. The generated configuration file (intended for use
by the client) contains the server's identity. For example, the following code is generated from a
service that specifies a DNS identity, as shown in the preceding example. Note that the client's
endpoint identity value matches that of the service. In this case, when the client receives the
Windows (Kerberos) credentials for the service, it expects the value to be contoso.com.
XML
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<bindingname="WSHttpBinding_ICalculator_Windows">
<security>
<messageclientCredentialType="Windows"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpointaddress="http://localhost:8003/servicemodelsamples/service/dnsidenti
ty"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator_Windows"
contract="ICalculator"
name="WSHttpBinding_ICalculator">
<identity>
<dnsvalue="contoso.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>

If, instead of Windows, the service specifies a certificate as the client credential type, then the
certificate's DNS property is expected to be the value contoso.com. (Or if the DNS property is
null, the certificate's subject name must be contoso.com.)
Using a Specific Value for Identity
The following client configuration file shows how the service's identity is expected to be a
specific value. In the following example, the client can communicate with two endpoints. The
first is identified with a certificate thumbprint and the second with a certificate RSA key. That is,
a certificate that contains only a public key/private key pair, but is not issued by a trusted
authority.
XML
<configuration>
<system.serviceModel>
Resource Links for 70-513 WCF Certification Exam
314
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<bindings>
<wsHttpBinding>
<bindingname="WSHttpBinding_ICalculator_Anonymous">
<security>
<messageclientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint
address="http://localhost:8003/servicemodelsamples/service/certificateidentit
y"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator_Anonymous"
contract="ICalculator"
name="WSHttpBinding_ICalculator1">
<identity>
<certificateencodedValue="AwAAAAEAAAAUAAAARwEDOI5fk5i0+TbylJ9k8Kljle8gAAAAAQA
AAMoBAAAwggHGMIIBdKADAgECAhCZcmDK722ujUz3waJ+O26gMAkGBSsOAwIdBQAwFjEUMBIGA1UE
AxMLUm9vdCBBZ2VuY3kwHhcNMDYwNTE3MjE0NDI1WhcNMzkxMjMxMjM1OTU5WjApMRAwDgYDVQQKE
wdDb250b3NvMRUwEwYDVQQDEwxpZGVudGl0eS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAo
GBAMGaK9xvyFhuHXWGpWgO4HvOYnbLbfR/9vh77g/rJe0oq6FR1hwipzyYB+isgzhZYkRUZ4lWr2w
UTCqsvlHKJ3yMxNHA8u8D/H/C+PWC0PUZYn5pSHamqJ6IYvsxZN6kcBAEiJtTGA6sA7PSP1eGDSIM
VhJx1hSN6ojfJkgMLtZvAgMBAAGjSzBJMEcGA1UdAQRAMD6AEBLkCS0GHR1PAI1hIdwWZGOhGDAWM
RQwEgYDVQQDEwtSb290IEFnZW5jeYIQBjdsAKoAZIoRz7jUqlw19DAJBgUrDgMCHQUAA0EAMH8nZC
N1I8vwOiPekC94Jd3/l9jTd6j2RTKb9OZvi5t2qw5uuLSqdhH+fxbGxrXIngOSzpw0FM9LiXkHvNR
42g==" />
</identity>
</endpoint>
<endpointaddress="http://localhost:8003/servicemodelsamples/service/rsaidenti
ty"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator_Anonymous"
contract="ICalculator"
name="WSHttpBinding_ICalculator2">
<identity>
<rsavalue="&lt;RSAKeyValue&gt;&lt;Modulus&gt;wZor3G/IWG4ddYalaA7ge85idstt9H/2
+HvuD+sl7SiroVHWHCKnPJgH6KyDOFliRFRniVavbBRMKqy+UconfIzE0cDy7wP8f8L49YLQ9Rlif
mlIdqaonohi+zFk3qRwEASIm1MYDqwDs9I/V4YNIgxWEnHWFI3qiN8mSAwu1m8=&lt;/Modulus&g
t;&lt;Exponent&gt;AQAB&lt;/Exponent&gt;&lt;/RSAKeyValue&gt;" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>

Identity Checking at Run Time
At design time, a client developer determines the server's identity through its metadata. At
runtime, the identity check is performed before calling any endpoints on the service.
The identity value is tied to the type of authentication specified by metadata; in other words, the
type of credentials used for the service.
If the channel is configured to authenticate using message- or transport-level Secure Sockets
Layer (SSL) with X.509 certificates for authentication, the following identity values are valid:
Resource Links for 70-513 WCF Certification Exam
315
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
DNS. WCF ensures that the certificate provided during the SSL handshake contains a DNS or
CommonName (CN) attribute equal to the value specified in the DNS identity on the client. Note that
these checks are done in addition to determining the validity of the server certificate. By default, WCF
validates that the server certificate is issued by a trusted root authority.
Certificate. During the SSL handshake, WCF ensures that the remote endpoint provides the exact
certificate value specified in the identity.
Certificate Reference. Same as Certificate.
RSA. During the SSL handshake, WCF ensures that the remote endpoint provides the exact RSA key
specified in the identity.
If the service authenticates using message- or transport-level SSL with a Windows credential for
authentication, and negotiates the credential, the following identity values are valid:
DNS. The negotiation passes the service's SPN so that the DNS name can be checked. The SPN is in the
form host/<dns name>.
SPN. An explicit service SPN is returned, for example, host/myservice.
UPN. The UPN of the service account. The UPN is in the form username@domain. For example, when
the service is running in a user account, it may be username@contoso.com.
Specifying the identity programmatically (using the Identity property) is optional. If no identity
is specified, and the client credential type is Windows, the default is SPN with the value set to
the hostname part of the service endpoint address prefixed with the "host/" literal. If no identity
is specified, and the client credential type is a certificate, the default is Certificate. This applies
to both message- and transport-level security.
Identity and Custom Bindings
Because the identity of a service depends on the binding type used, ensure that an appropriate
identity is exposed when creating a custom binding. For example, in the following code example,
the identity exposed is not compatible with the security type, because the identity for the secure
conversation bootstrap binding does not match the identity for the binding on the endpoint. The
secure conversation binding sets the DNS identity, while the
WindowsStreamSecurityBindingElement sets the UPN or SPN identity.
C#
VB
CustomBinding binding = new CustomBinding();
// The following binding exposes a DNS identity.
binding.Elements.Add(SecurityBindingElement.
CreateSecureConversationBindingElement(
SecurityBindingElement.
CreateIssuedTokenForSslBindingElement(
new IssuedSecurityTokenParameters())));

// The following element requires a UPN or SPN identity.
binding.Elements.Add(new WindowsStreamSecurityBindingElement());
binding.Elements.Add(new TcpTransportBindingElement());

For more information about how to stack binding elements correctly for a custom binding, see
Creating User-Defined Bindings. For more information about creating a custom binding with the
SecurityBindingElement, see How to: Create a SecurityBindingElement for a Specified
Authentication Mode.
Resource Links for 70-513 WCF Certification Exam
316
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Security Negotiation and Timeouts
When clients and services authenticate, Windows Communication Foundation (WCF) supports a
mode where the service credential is negotiated as part of authentication. In such scenarios, a
potentially multileg exchange occurs between the client and the service in order to propagate the
service credential to the client. The NegotiationTimeout property controls how long the multileg
exchange can take to complete. However, this timeout only applies if the exchange actually takes
more that a single request-response. In cases where the negotiation completes in a single round
trip, the timeout does not apply.
Debugging Windows Authentication Errors
When using Windows authentication as a security mechanism, the Security Support Provider
Interface (SSPI) handles security processes. When security errors occur at the SSPI layer, they
are surfaced by Windows Communication Foundation (WCF). This topic provides a framework
and set of questions to help diagnose the errors.
For an overview of the Kerberos protocol, see Kerberos Explained; for an overview of SSPI, see
SSPI.
For Windows authentication, WCF typically uses the Negotiate Security Support Provider (SSP),
which performs Kerberos mutual authentication between the client and service. If the Kerberos
protocol is not available, by default WCF falls back to NT LAN Manager (NTLM). However,
you can configure WCF to use only the Kerberos protocol (and to throw an exception if Kerberos
is not available). You can also configure WCF to use restricted forms of the Kerberos protocol.
Debugging Methodology
The basic method is as follows:
1. Determine whether you are using Windows authentication. If you are using any other scheme, this topic
does not apply.
2. If you are sure you are using Windows authentication, determine whether your WCF configuration uses
Kerberos direct or Negotiate.
3. Once you have determined whether your configuration is using the Kerberos protocol or NTLM, you can
understand error messages in the correct context.
Availability of the Kerberos Protocol and NTLM
The Kerberos SSP requires a domain controller to act as the Kerberos Key Distribution Center
(KDC). The Kerberos protocol is available only when both the client and service are using
domain identities. In other account combinations, NTLM is used, as summarized in the following
table.
The table headers show possible account types used by the server. The left column shows
possible account types used by the client.

Local User Local System Domain User Domain Machine
Local User NTLM NTLM NTLM NTLM
Local System
Anonymous
NTLM
Anonymous
NTLM
Anonymous
NTLM
Anonymous
NTLM
Domain User NTLM NTLM Kerberos Kerberos
Domain
Machine
NTLM NTLM Kerberos Kerberos
Resource Links for 70-513 WCF Certification Exam
317
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Specifically, the four account types include:
Local User: Machine-only user profile. For example: MachineName\Administrator or
MachineName\ProfileName.
Local System: The built-in account SYSTEM on a machine that is not joined to a domain.
Domain User: A user account on a Windows domain. For example: DomainName\ProfileName.
Domain Machine: A process with machine identity running on a machine joined to a Windows domain.
For example: MachineName\Network Service.
Note:
The service credential is captured when the Open method of the ServiceHost class is called. The client
credential is read whenever the client sends a message.
Common Windows Authentication Problems
This section discusses some common Windows authentication problems and possible remedies.
Kerberos Protocol
SPN/UPN Problems with the Kerberos Protocol
When using Windows authentication, and the Kerberos protocol is used or negotiated by SSPI,
the URL the client endpoint uses must include the fully qualified domain name of the service's
host inside the service URL. This assumes that the account under which the service is running
has access to the machine (default) service principal name (SPN) key that is created when the
computer is added to the Active Directory domain, which is most commonly done by running the
service under the Network Service account. If the service does not have access to the machine
SPN key, you must supply the correct SPN or user principal name (UPN) of the account under
which the service is running in the client's endpoint identity. For more information about how
WCF works with SPN and UPN, see Service Identity and Authentication.
In load-balancing scenarios, such as Web farms or Web gardens, a common practice is to define
a unique account for each application, assign an SPN to that account, and ensure that all of the
application's services run in that account.
To obtain an SPN for your service's account, you need to be an Active Directory domain
administrator. For more information, see Kerberos Technical Supplement for Windows.
Kerberos Protocol Direct Requires the Service to Run Under a Domain Machine Account
This occurs when the ClientCredentialType property is set to Windows and the
NegotiateServiceCredential property is set to false, as shown in the following code.
C#
VB
WSHttpBinding b = new WSHttpBinding();
// By default, the WSHttpBinding uses Windows authentication
// and Message mode.
b.Security.Message.NegotiateServiceCredential = false;

To remedy, run the service using a Domain Machine account, such as Network Service, on a
domain joined machine.
Delegation Requires Credential Negotiation
To use the Kerberos authentication protocol with delegation, you must implement the Kerberos
protocol with credential negotiation (sometimes called "multi-leg" or "multi-step" Kerberos). If
you implement Kerberos authentication without credential negotiation (sometimes called "one-
shot" or "single-leg" Kerberos), an exception will be thrown.
Resource Links for 70-513 WCF Certification Exam
318
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
To implement Kerberos with credential negotiation, do the following steps:
1. Implement delegation by setting AllowedImpersonationLevel to Delegation.
2. Require SSPI negotiation:
1. If you are using standard bindings, set the NegotiateServiceCredential property to true.
2. If you are using custom bindings, set the AuthenticationMode attribute of the Security element to
SspiNegotiated.
3. Require the SSPI negotiation to use Kerberos by disallowing the use of NTLM:
1. Do this in code, with the following statement:
ChannelFactory.Credentials.Windows.AllowNtlm = false
2. Or you can do this in the configuration file by setting the allowNtlm attribute to false. This attribute is
contained in the <windows> of <clientCredentials> element.
NTLM Protocol
Negotiate SSP Falls Back to NTLM, but NTLM Is Disabled
The AllowNtlm property is set to false, which causes Windows Communication Foundation
(WCF) to make a best-effort to throw an exception if NTLM is used. Note that setting this
property to false may not prevent NTLM credentials from being sent over the wire.
The following shows how to disable fallback to NTLM.
C#
VB
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowNtlm = false;

NTLM Logon Fails
The client credentials are not valid on the service. Check that the user name and password are
correctly set and correspond to an account that is known to the computer where the service is
running. NTLM uses the specified credentials to log on to the service's computer. While the
credentials may be valid on the computer where the client is running, this logon will fail if the
credentials are not valid on the service's computer.
Anonymous NTLM Logon Occurs, but Anonymous Logons Are Disabled by Default
When creating a client, the AllowedImpersonationLevel property is set to Anonymous, as
shown in the following example, but by default the server disallows anonymous logons. This
occurs because the default value of the AllowAnonymousLogons property of the
WindowsServiceCredential class is false.
The following client code attempts to enable anonymous logons (note that the default property is
Identification).
C#
VB
CalculatorClient cc =
new CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Anonymous;

The following service code changes the default to enable anonymous logons by the server.
C#
VB
Uri httpUri = new Uri("http://localhost:8000/");
Resource Links for 70-513 WCF Certification Exam
319
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
ServiceHost sh = new ServiceHost(typeof(Calculator), httpUri);
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = true;

For more information about impersonation, see Delegation and Impersonation with WCF.
Alternatively, the client is running as a Windows service, using the built-in account SYSTEM.
Other Problems
Client Credentials Are Not Set Correctly
Windows authentication uses the WindowsClientCredential instance returned by the
ClientCredentials property of the ClientBase class, not the UserNamePasswordClientCredential.
The following shows an incorrect example.
C#
VB
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.UserName.UserName = GetUserName(); // wrong!
cc.ClientCredentials.UserName.Password = GetPassword(); // wrong!

The following shows the correct example.
C#
VB
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
// This code returns the WindowsClientCredential type.
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName();
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword();

SSPI Is Not Available
The following operating systems do not support Windows authentication when used as a server:
Windows XP Home Edition, Windows XP Media Center Edition, and Windows Vista Home
editions.
Developing and Deploying with Different Identities
If you develop your application on one machine, and deploy on another, and use different
account types to authenticate on each machine, you may experience different behavior. For
example, suppose you develop your application on a Windows XP Pro machine using the SSPI
Negotiated authentication mode. If you use a local user account to authenticate with, then
NTLM protocol will be used. Once the application is developed, you deploy the service to a
Windows Server 2003 machine where it runs under a domain account. At this point the client
will not be able to authenticate the service because it will be using Kerberos and a domain
controller.

Implement Authorization.This objective may include but is not limited to: role based, claim
based; configuring role providers for endpoints; principal permission attributeThis objective does
not include: rights-management authorization such as Active Directory Rights Management
Services (AD RMS)
Access Control Mechanisms
You can control access in several way with Windows Communication Foundation (WCF). This
topic briefly discusses the various mechanisms and provides suggestions on when to use each; it
Resource Links for 70-513 WCF Certification Exam
320
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
is intended to help you select the correct mechanism to use. The access technologies are listed in
order of complexity. The simplest is the PrincipalPermissionAttribute; the most complex is the
Identity Model.
In addition to these mechanisms, impersonation and delegation with WCF is explained in
Delegation and Impersonation with WCF.
PrincipalPermissionAttribute
The PrincipalPermissionAttribute is used to restrict access to a service method. When the
attribute is applied to a method, it can be used to demand a specific caller's identity or
membership in a Windows group or ASP.NET role. If the client is authenticated using an X.509
certificate, it is given a primary identity that consists of the subject name plus the thumbprint of
the certificate.
Use the PrincipalPermissionAttribute to control access to resources on the computer that the
service is running on, and if the users of the service will always be part of the same Windows
domain that the service is running on. You can easily create Windows groups that have specified
levels of access (such as none, read-only, or read and write).
For more information about using the attribute, see How to: Restrict Access with the
PrincipalPermissionAttribute Class. For more information about identity, see Service Identity
and Authentication.
ASP.NET Membership Provider
A feature of ASP.NET is the membership provider. Even though the membership provider is not
technically an access control mechanism, it allows controlling access to the service by limiting
the set of possible identities that can access the service's endpoint. The membership feature
includes a database that can be populated with user name/password combinations that enable
users of a Web site to establish accounts with the site. To access a service that uses the
membership provider, a user must log on with his or her user name and password.
Note:
You must first populate the database using the ASP.NET feature before a WCF service can use it for
authorization purposes.
You can also use the membership feature if you already have a membership database from an
existing ASP.NET Web site and you want to enable the same users to use your service,
authorized with the same user names and passwords.
For more information about using the membership feature in a WCF service, see How to: Use
the ASP.NET Membership Provider.
ASP.NET Role Provider
Another feature of ASP.NET is the ability to manage authorization using roles. The ASP.NET
role provider enables a developer to create roles for users and to assign each user to a role or
roles. As with the membership provider, the roles and assignments are stored in a database, and
can be populated using tools provided by a particular implementation of the ASP.NET role
provider. As with the membership feature, WCF developers can use the information in the
database to authorize service users by roles. They can, for example, use the role provider in
combination with the PrincipalPermissionAttribute access control mechanism described
above.
Resource Links for 70-513 WCF Certification Exam
321
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
You can also use the ASP.NET role provider if you have an existing ASP.NET role provider
database and want to use the same set of rules and user assignments in your WCF service.
For more information about using the role provider feature, see How to: Use the ASP.NET Role
Provider with a Service.
Authorization Manager
Another feature combines the Authorization Manager (AzMan) with the ASP.NET role provider
to authorize clients. When ASP.NET hosts a Web service, AzMan can be integrated into the
application so that authorization to the service is done through AzMan. ASP.NET role manager
provides an API that enables you to manage application roles, add and remove users from roles,
and check role membership, but it does not allow you to query whether a user is authorized to
perform a named task or operation. AzMan allows you to define individual operations and
combine them into tasks. With AZMan, in addition to role checks, you can also check whether a
user can perform a task. Role assignment and task authorization can be configured outside of the
application or performed programmatically within the application. The AzMan administration
Microsoft Management Console (MMC) snap-in allows administrators to change the tasks a role
can perform at run time and to manage each user's membership of roles.
You can also use AzMan and the ASP.NET role provider if you already have access to an
existing AzMan installation and want to authorize your service users using the features of the
AzMan/role provider combination.
For more information about AzMan and the ASP.NET role provider, see . For more information
about using AzMan and the role provider for WCF services, see How to: Use the ASP.NET
Authorization Manager Role Provider with a Service.
Identity Model
The Identity Model is a set of APIs that enable you to manage claims and policies to authorize
clients. With the Identity Model, you can examine every claim contained in credentials that the
caller used to authenticate itself to the service, compare the claims to the set of policies for the
service, and grant or deny access based on the comparison.
Use the Identity Model if you need fine control and the ability to set specific criteria before
granting access. For example, when using the PrincipalPermissionAttribute, the criterion is
simply that the identity of the user is authenticated and belongs to a specific role. In contrast,
using the Identity Model, you can create a policy that states the user must be over 18 years of age
and possesses a valid driver's license before being allowed to view a document.
One example where you can benefit from the Identity Model claim-based access control is when
using federation credentials in the issued token scenario. For more information about federation
and issued tokens, see Federation and Issued Tokens.
For more information about the Identity Model, see Managing Claims and Authorization with the
Identity Model.
How to: Restrict Access with the
PrincipalPermissionAttribute Class
Controlling the access to resources on a Windows-domain computer is a basic security task. For
example, only certain users should be able to view sensitive data, such as payroll information.
This topic explains how to restrict access to a method by demanding that the user belong to a
predefined group. For a working sample, see Authorizing Access to Service Operations.
Resource Links for 70-513 WCF Certification Exam
322
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The task consists of two separate procedures. The first creates the group and populates it with
users. The second applies the PrincipalPermissionAttribute class to specify the group.
To create a Windows group
1. Open the Computer Management console.
2. In the left panel, click Local Users and Groups.
3. Right-click Groups, and click New Group.
4. In the Group Name box, type a name for the new group.
5. In the Description box, type a description of the new group.
6. Click the Add button to add new members to the group.
7. If you have added yourself to the group and want to test the following code, you must log off the
computer and log back on to be included in the group.
To demand user membership
1. Open the Windows Communication Foundation (WCF) code file that contains the implemented
service contract code. For more information about implementing a contract, see Implementing
Service Contracts.
2. Apply the PrincipalPermissionAttribute attribute to each method that must be restricted to a
specific group. Set the Action property to Demand and the Role property to the name of the
group. For example:
C#
VB
// Only members of the CalculatorClients group can call this method.
[PrincipalPermission(SecurityAction.Demand, Role = "CalculatorClients")]
publicdouble Add(double a, double b)
{
return a + b;
}

Note:
If you apply the PrincipalPermissionAttribute attribute to a contract a SecurityException will be
thrown. You can only apply the attribute at the method level.
Using a Certificate to Control Access to a Method
You can also use the PrincipalPermissionAttribute class to control access to a method if the
client credential type is a certificate. To do this, you must have the certificate's subject and
thumbprint.
To examine a certificate for its properties, see How to: View Certificates with the MMC Snap-in.
To find the thumbprint value, see How to: Retrieve the Thumbprint of a Certificate.
To control access using a certificate
1. Apply the PrincipalPermissionAttribute class to the method you want to restrict access to.
2. Set the action of the attribute to System.Security.Permissions.SecurityAction.Demand.
3. Set the Name property to a string that consists of the subject name and the certificate's
thumbprint. Separate the two values with a semicolon and a space, as shown in the following
example:
C#
VB
Resource Links for 70-513 WCF Certification Exam
323
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
// Only a client authenticated with a valid certificate that has the
// specified subject name and thumbprint can call this method.
[PrincipalPermission(SecurityAction.Demand,
Name = "CN=ReplaceWithSubjectName;
123456712345677E8E230FDE624F841B1CE9D41E")]
publicdouble Multiply(double a, double b)
{
return a * b;
}

4. Set the PrincipalPermissionMode property to UseAspNetRoles as shown in the following
configuration example:
5. <behaviors>
6. <serviceBehaviors>
7. <behavior name="SvcBehavior1">
8. <serviceAuthorization principalPermissionMode="UseAspNetRoles" />
9. </behavior>
10. </serviceBehaviors>
11. </behaviors>
Setting this value to UseAspNetRoles indicates that the Name property of the
PrincipalPermissionAttribute will be used to perform a string comparison. When a certificate
is used as a client credential, by default WCF concatenates the certificate common name and the
thumbprint with a semicolon to create a unique value for the client's primary identity. With
UseAspNetRoles set as the PrincipalPermissionMode on the service, this primary identity
value is compared with the Name property value to determine the access rights of the user.
Alternatively, when creating a self-hosted service, set the PrincipalPermissionMode property in
code as shown in the following code:
C#
VB
ServiceHost myServiceHost = new ServiceHost(typeof(Calculator), baseUri);
ServiceAuthorizationBehavior myServiceBehavior =
myServiceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
myServiceBehavior.PrincipalPermissionMode =
PrincipalPermissionMode.UseAspNetRoles;

How to: Use the ASP.NET Role Provider with
a Service
The ASP.NET role provider (in conjunction with the ASP.NET membership provider) is a
feature that enables ASP.NET developers to create Web sites that allow users to create an
account with a site and to be assigned roles for authorization purposes. With this feature, any
user can establish an account with the site, and log in for exclusive access to the site and its
services. This is in contrast to Windows security, which requires users to have accounts in a
Windows domain. Instead, any user who supplies his or her credentials (the user name/password
combination) can use the site and its services.
For a sample application, see Membership and Role Provider. For more information about the
ASP.NET membership provider feature, see How to: Use the ASP.NET Membership Provider.
Resource Links for 70-513 WCF Certification Exam
324
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The role provider feature uses a SQL Server database to store user information. Windows
Communication Foundation (WCF) developers can take advantage of these features for security
purposes. When integrated into a WCF application, users must supply a user name/password
combination to the WCF client application. To enable WCF to use the database, you must create
an instance of the ServiceAuthorizationBehavior class, set its PrincipalPermissionMode property
to UseAspNetRoles, and add the instance to the collection of behaviors to the ServiceHost that is
hosting the service.
To configure the role provider
1. In the Web.config file, under the <system.web> element, add a <roleManager> element and set
its enabled attribute to true.
2. Set the defaultProvider attribute to SqlRoleProvider.
3. As a child to the <roleManager> element, add a <providers> element.
4. As a child to the <providers> element, add an <add> element with the following attributes set to
appropriate values: name, type, connectionStringName, and applicationName, as shown in the
following example.
5. <!-- Configure the Sql Role Provider. -->
6. <roleManager enabled ="true"
7. defaultProvider ="SqlRoleProvider" >
8. <providers>
9. <add name ="SqlRoleProvider"
10. type="System.Web.Security.SqlRoleProvider"
11. connectionStringName="SqlConn"
12. applicationName="MembershipAndRoleProviderSample"/>
13. </providers>
14. </roleManager>
To configure the service to use the role provider
1. In the Web.config file, add a <system.ServiceModel> element.
2. Add a <behaviors> element to the <system.ServiceModel> element.
3. Add a serviceBehaviors section to the <behaviors> element.
4. Add a Behavior element element and set the name attribute to an appropriate value.
5. Add a <serviceAuthorization> element to the <behavior> element.
6. Set the principalPermissionMode attribute to UseAspNetRoles.
7. Set the roleProviderName attribute to SqlRoleProvider. The following example shows a
fragment of the configuration.
8. <behaviors>
9. <serviceBehaviors>
10. <behavior name="CalculatorServiceBehavior">
11. <serviceAuthorization principalPermissionMode ="UseAspNetRoles"
12. roleProviderName ="SqlRoleProvider" />
13. </behavior>
14. </serviceBehaviors>
15. </behaviors>
How to: Use the ASP.NET Authorization
Manager Role Provider with a Service
When ASP.NET hosts a Web service, you can integrate Authorization Manager into the
application to provide authorization to the service. Authorization Manager enables an application
Resource Links for 70-513 WCF Certification Exam
325
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
developer to define individual operations, which can be grouped together to form tasks. An
administrator can then authorize roles to perform specific tasks or individual operations.
Authorization Manager provides an administration tool as a Microsoft Management Console
(MMC) snap-in to manage roles, tasks, operations, and users. Administrators configure an
Authorization Manager policy store in an XML file, Active Directory, or in an Active Directory
Application Mode (ADAM) store.
Authorization Manager is Integrated into the application by configuring the Authorization
Manager ASP.NET role provider for the ASP.NET application that is hosting the Web service.
Like other ASP.NET role providers, the Authorization Manager ASP.NET role provider is
configured using the <providers> element.
The following code example is a portion of a configuration file for a Web service that is
integrating Authorization Manager into the application.
<system.web>
<roleManager enabled="true" defaultProvider="AzManRoleProvider">
<providers>
<add name="AzManRoleProvider"
type="System.Web.Security.AuthorizationStoreRoleProvider,
System.Web, Version=2.0.0.0, Culture=neutral,
publicKeyToken=b03f5f7f11d50a3a"
connectionStringName="AzManPolicyStoreConnectionString"
applicationName="SecureService"/>
</providers>
</roleManager>
</system.web>
For more information about integrating an ASP.NET role provider with a WCF application, see
How to: Use the ASP.NET Role Provider with a Service. For more information about using
Authorization Manager with ASP.NET, see How to: Use Authorization Manager (AzMan) with
ASP.NET 2.0.
Managing Claims and Authorization with the
Identity Model
Authorization is the process of determining which entities have permission to change, view, or
otherwise access a computer resource. For example, in a business, only managers may be
allowed to access the files of their employees. Windows Communication Foundation (WCF)
supports two mechanisms for performing authorization processing. The first mechanism enables
you to control authorization using existing common language runtime (CLR) constructs. The
second is a claims-based model known as the Identity Model. WCF uses the Identity Model to
create claims from incoming messages; Identity Model classes can be extended to support new
claim types for custom authorization schemes. This topic presents an overview of the major
programming concepts of the Identity Model feature, as well as a listing of the most important
classes the feature uses.
Identity Model Scenarios
The following scenarios represent Identity Model use.
Scenario 1: Supporting Identity, Role, and Group Claims
Resource Links for 70-513 WCF Certification Exam
326
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Users send messages to a Web service. The access control requirements of the Web service use
identity, roles, or groups. The message sender is mapped to a set of roles or groups. Role or
group information is used to perform access checks.
Scenario 2: Supporting Rich Claims
Users send messages to a Web service. The access control requirements of the Web service
require a richer model than identity, roles, or groups. The Web service determines whether a
given user has access to a particular protected resource using the rich claims-based model. For
example, one user may be able to read particular information, such as salary information, that
other users do not have access to.
Scenario 3: Mapping Disparate Claims
A user sends a message to a Web service. The user may specify their credentials in a number of
different ways: X.509 certificate, user name token, or Kerberos token. The Web service is
required to perform access control checks in the same way, regardless of the user credential type.
If additional credential types are supported over time, the system should evolve accordingly.
Scenario 4: Determining Access to Multiple Resources
A Web service attempts to access multiple resources. The service determines which protected
resources a given user has access to by comparing the claims associated with the user with the
claims required to access the resource.
Identity Model Terms
The following list defines key terms used to describe Identity Model concepts.
Authorization policy
A set of rules for mapping a set of input claims to a set of output claims. Evaluating authorization policy
results in claim sets being added to an evaluation context and subsequently an authorization context.
Authorization context
A set of claim sets and zero or more properties. The result of evaluating one or more authorization
policies.
Claim
A combination of a claim type, right, and a value.
Claim set
A set of claims issued by a particular issuer.
Claim type
A kind of claim. Claims defined by the Identity Model API are properties of the ClaimType class.
Examples of system-provided claim types are Dns, Email, Hash, Name, Rsa, Sid, Spn, System,
Thumbprint, Uri, and X500DistinguishedName.
Evaluation context
A context in which an authorization policy is evaluated. Contains properties and claim sets. Becomes the
basis of an authorization context once evaluation is complete.
Identity claim
A claim whose right is identity.
Issuer
A claim set that contains at least one identity claim and is considered to have issued another claim set.
Properties
Resource Links for 70-513 WCF Certification Exam
327
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
A set of information associated with an evaluation context or authorization context.
Protected resource
Something in the system that can only be used, accessed, or otherwise manipulated if certain
requirements are first met.
Right
A capability over a resource. Rights defined by the Identity Model API are properties of the Rights class.
Examples of system-provided rights are Identity and PossessProperty.
Value
Something over which a right is claimed.
Claims
The Identity Model is a claims-based system. Claims describe the capabilities associated with
some entity in the system, often a user of that system. The set of claims associated with a given
entity can be thought of as a key. The particular claims define the shape of that key, similar to a
physical key used to open a lock in a door. Claims are used to gain access to resources. Access to
a given protected resource is determined by comparing the claims needed to access that resource
with the claims associated with the entity attempting access.
A claim is the expression of a right with respect to a particular value. A right could be something
like "Read", "Write", or "Execute." A value could be a database, a file, a mailbox, or a property.
Claims also have a claim type. The combination of claim type and right provides the mechanism
for specifying capabilities with respect to the value. For example, a claim of type "File", with
right "Read" over the value "Biography.doc", indicates that the entity with which such a claim is
associated has read access to the file Biography.doc. A claim of type "Name", with right
"PossessProperty" over the value "Martin", indicates that the entity with which such a claim is
associated possesses a Name property with the value "Martin".
Although various claim types and rights are defined as part of the Identity Model, the system is
extensible, allowing the various systems, building on top of the Identity Model infrastructure, to
define additional claim types and rights as required.
Identity Claims
One particular right is that of identity. Claims that possess this right make a statement about the
identity of the entity. For example, a claim of type "user principal name" (UPN) with a value of
"someone@example.com" and a right of Identity indicates a particular identity in a particular
domain.
System Identity Claim
The Identity Model defines one identity claim: System. The System identity claim indicates that
an entity is the current application or system.
Sets of Claims
The model of claims that represent identity is important because claims are always issued by
some entity in the system, even if that entity is ultimately some concept of "self". Claims are
grouped together as a set and each set has an issuer. An issuer is just a set of claims. Such a
recursive relationship must eventually end and any claim set can be its own issuer.
The following figure shows an example of three sets of claims where one set of claims has, as its
issuer, another set of claims, which in turn has the System claim set as its issuer. Therefore, sets
of claims form a hierarchy that may be arbitrarily deep.
Resource Links for 70-513 WCF Certification Exam
328
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

Multiple sets of claims may have the same issuing claim set, as illustrated in the following
figure.
Resource Links for 70-513 WCF Certification Exam
329
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

With the exception of a claim set that is its own issuer, the Identity Model does not provide any
support for claim sets to form a loop. Thus a situation where claim set A is issued by claim set B,
which is itself issued by claim set A, can never arise. Also, the Identity Model does not provide
any support for claim sets to have multiple issuers. If two or more issuers must issue a given set
of claims, then you must use multiple claim sets, each containing the same claims, but having
different issuers.
The Origin of Claims
Claims can come from a variety of sources. One common source of claims is credentials
presented by a user, for example as part of a message sent to a Web service. The system validates
such claims, and they become part of a set of claims associated with the user. Other system
components may also be sources of claims, including, but not limited to, the operating system,
the network stack, the run-time environment, or the application. In addition, remote services may
also be a source of claims.
Authorization Policies
In the Identity Model, claims are generated as part of the process of evaluating the authorization
policy. An authorization policy examines the (possibly empty) set of existing claims and may
choose to add additional claims based on the claims already present and additional information at
its disposal. This provides the basis of mapping between claims. The presence or absence of
claims in the system influences the behavior of an authorization policy with respect to whether it
adds additional claims.
For example, the authorization policy has access to a database that includes the birthdates of the
various entities using the system. The authorization policy uses that information to add an
"Over18" claim to the context. Note that this Over18 claim does not disclose any information
about the entity other than the fact that it is over 18 years of age. Note that interpretation of the
Resource Links for 70-513 WCF Certification Exam
330
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
'Over18' claim depends on understanding the semantics of that claim. The authorization policy
that added the claim understands those semantics at some level. Code that subsequently
examines the claims that result from policy evaluation also be informed of those semantics.
A given authorization policy may require that it be evaluated multiple times because, as other
authorization policies add claims, that authorization policy might add yet more claims. Identity
Model is designed to continue evaluation until no more claims are added to the context by any of
the authorization policies in force. This continued evaluation of authorization policies prevents
the requirement to enforce any specific evaluation order with respect to authorization policies;
they can be evaluated in any order. For example, if policy X only adds Claim Z if policy A has
added Claim B, then if X is evaluated first, it initially does not add the Claim Z. Subsequently, A
is evaluated and adds Claim B. X is then evaluated a second time, and this time it adds Claim Z.
A given system may have many authorization policies in force.
A Key-Making Machine
Evaluating a group of associated authorization policies is like using a machine that makes keys.
The authorization policies are each evaluated and sets of claims are generated, building up the
shape of the key. Once the shape of the key is completed, it can be used to try to open some
locks. The shape of the key is stored in an "authorization context," which is created by an
authorization manager.
Authorization Context
An authorization manager evaluates the various authorization policies as described, and the
result is an authorization context (a set of claim sets and some associated properties). The
authorization context can be examined to determine what claims are present in that context, the
relationships between those various claims (for example, the issuing claim set), and ultimately
compare them against some requirements they must meet to access a resource.
Locks
If an authorization context (a set of claims) is a key, then the requirements that must be satisfied
to grant access to a particular protected resource constitute the lock that the key must fit. Identity
Model does not formalize how such requirements are expressed but they do, given the claim-
based nature of the system, involve comparing the claims in the authorization context against
some set of required claims.
A Recap
Identity Model is based around the concept of claims. Claims are grouped into sets and
aggregated in an authorization context. An authorization context contains a set of claims and is
the result of evaluating one or more authorization policies associated with an authorization
manager. These claim sets can be examined to determine if access requirements have been met.
The following figure shows the relationships between these various Identity Model concepts.
Resource Links for 70-513 WCF Certification Exam
331
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

WCF and Identity Model
WCF uses the Identity Model infrastructure as the basis for performing authorization. In WCF,
the ServiceAuthorizationBehavior class allows you to specify authorization policies as part of a
service. Such authorization policies are known as external authorization policies, and they can
perform claim processing based on local policy or by interaction with a remote service. The
authorization manager, represented by the ServiceAuthorizationManager class evaluates external
authorization policies together with authorization policies that recognize the various credential
types (tokens) and populates what is called an authorization context with the claims appropriate
to an incoming message. The authorization context is represented by the AuthorizationContext
class.
Identity Model Programming
The following table describes the object model used to program Identity Model extensions.
These classes all exist in either the System.IdentityModel.Policy or the
System.IdentityModel.Claims namespaces.
Class Description
Authorization Component An Identity Model class that implements the
Resource Links for 70-513 WCF Certification Exam
332
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
IAuthorizationComponent interface.
IAuthorizationComponent
An interface that provides a single read-only string property: Id.
The value of this property is unique for each instance in the system
that implements this interface.
AuthorizationContext
An authorization component that contains a set of ClaimSet
instances with zero or more properties; the result of evaluating one
or more Authorization Policies.
Claim
A combination of a claim type, right, and value. The right and value
parts are constrained by the claim type.
ClaimSet An abstract base class. A collection of Claim instances.
DefaultClaimSet A sealed class. An implementation of the ClaimSet class.
EvaluationContext
An abstract base class. Passed to an authorization policy during
policy evaluation.
IAuthorizationPolicy
An interface derived from IAuthorizationComponent and
implemented by authorization policy classes.
Rights A static class that contains predefined right values.
The following classes are also used for Identity Model programming, but are not found in the
System.IdentityModel.Policy or System.IdentityModel.Claims namespaces.
Class Description
ServiceAuthorizationManager
A class that provides a method CheckAccessCoreto
perform claim-based authorization checks for each operation in
a service. You must derive from the class and override the
method.
ServiceAuthorizationBehavior
A sealed class that provides various properties related to the
behavior of a service as it pertains to authorization.
ServiceSecurityContext
A class that provides security context, including authorization
context, for the currently running (or about to be run) operation.
An instance of this class is part of the OperationContext.
Significant Members
The following members are commonly used to create new claim types.
Member Description
CheckAccessCore
Derived classes implement this method to perform claim-based
access checks prior to running operations in a service. Any and all
information in the supplied OperationContext, or elsewhere, can
be examined when making the access check decision. If
CheckAccessCore returns true, then access is granted and the
operation is allowed to run. If CheckAccessCore returns false,
then access is denied and the operation does not run. For an
example, see How to: Create a Custom Authorization Manager
for a Service.
ServiceAuthorizationManager Returns the ServiceAuthorizationManager for the service. The
Resource Links for 70-513 WCF Certification Exam
333
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
ServiceAuthorizationManager is responsible for making
authorization decisions.
ExternalAuthorizationPolicies
The collection of custom authorization policies specified for the
service. These policies are evaluated in addition to those policies
associated with credentials in incoming messages.
Delegation and Impersonation with WCF
Impersonation is a common technique that services use to restrict client access to a service
domain's resources. Service domain resources can either be machine resources, such as local files
(impersonation), or a resource on another machine, such as a file share (delegation). For a sample
application, see Impersonating the Client Sample. For an example of how to use impersonation,
see How to: Impersonate a Client on a Service.
Note:
Be aware that when impersonating a client on a service, the service runs with the client's credentials,
which may have higher privileges than the server process.
Overview
Typically, clients call a service to have the service perform some action on the clients behalf.
Impersonation allows the service to act as the client while performing the action. Delegation
allows a front-end service to forward the clients request to a back-end service in such a way that
the back-end service can also impersonate the client. Impersonation is most commonly used as a
way of checking whether a client is authorized to perform a particular action, while delegation is
a way of flowing impersonation capabilities, along with the clients identity, to a back-end
service. Delegation is a Windows domain feature that can be used when Kerberos-based
authentication is performed. Delegation is distinct from identity flow and, because delegation
transfers the ability to impersonate the client without possession of the clients password, it is a
much higher privileged operation than identity flow.
Both impersonation and delegation require that the client have a Windows identity. If a client
does not possess a Windows identity, then the only option available is to flow the clients
identity to the second service.
Impersonation Basics
Windows Communication Foundation (WCF) supports impersonation for a variety of client
credentials. This topic describes service model support for impersonating the caller during the
implementation of a service method. Also discussed are common deployment scenarios
involving impersonation and SOAP security and WCF options in these scenarios.
This topic focuses on impersonation and delegation in WCF when using SOAP security. You can
also use impersonation and delegation with WCF when using transport security, as described in
Using Impersonation with Transport Security.
Two Methods
WCF SOAP security has two distinct methods for performing impersonation. The method used
depends on the binding. One is impersonation from a Windows token obtained from the Security
Support Provider Interface (SSPI) or Kerberos authentication, which is then cached on the
service. The second is impersonation from a Windows token obtained from the Kerberos
extensions, collectively called Service-for-User (S4U).
Resource Links for 70-513 WCF Certification Exam
334
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Cached Token Impersonation
You can perform cached-token impersonation with the following:
WSHttpBinding, WSDualHttpBinding, and NetTcpBinding with a Windows client credential.
BasicHttpBinding with a BasicHttpSecurityMode set to the TransportWithMessageCredential credential,
or any other standard binding where the client presents a user name credential that the service can map
to a valid Windows account.
Any CustomBinding that uses a Windows client credential with the requireCancellation set to true. (The
property is available on the following classes: SecureConversationSecurityTokenParameters,
SslSecurityTokenParameters, and SspiSecurityTokenParameters.) If a secure conversation is used on the
binding, it must also have the requireCancellation property set to true.
Any CustomBinding where the client presents a user name credential. If secure conversation is used on
the binding, it must also have the requireCancellation property set to true.
S4U-Based Impersonation
You can perform S4U-based impersonation with the following:
WSHttpBinding, WSDualHttpBinding, and NetTcpBinding with a certificate client credential that the
service can map to a valid Windows account.
Any CustomBinding that uses a Windows client credential with the requireCancellation property set to
false.
Any CustomBinding that uses a user name or Windows client credential and secure conversation with
the requireCancellation property set to false.
The extent to which the service can impersonate the client depends on the privileges the service
account holds when it attempts impersonation, the type of impersonation used, and possibly the
extent of impersonation the client permits.
Note:
When the client and service are running on the same computer and the client is running under a system
account (for example, Local System or Network Service), the client cannot be impersonated when a
secure session is established with stateful Security Context tokens. A Windows Form or console
application typically runs under the currently logged-in account, so that account can be impersonated by
default. However, when the client is an ASP.NET page and that page is hosted in IIS 6.0 or IIS 7.0, then
the client does run under the Network Service account by default. All of the system-provided bindings
that support secure sessions use a stateless security context token (SCT) by default. However, if the
client is an ASP.NET page, and secure sessions with stateful SCTs are used, the client cannot be
impersonated. For more information about using stateful SCTs in a secure session, see How to: Create a
Stateful Security Context Token for a Secure Session.
Impersonation in a Service Method: Declarative Model
Most impersonation scenarios involve executing the service method in the caller context. WCF
provides an impersonation feature that makes this easy to do by allowing the user to specify the
impersonation requirement in the OperationBehaviorAttribute attribute. For example, in the
following code, the WCF infrastructure impersonates the caller before executing the Hello
method. Any attempt to access native resources inside the Hello method succeed only if the
access control list (ACL) of the resource allows the caller access privileges. To enable
impersonation, set the Impersonation property to one of the ImpersonationOption enumeration
Resource Links for 70-513 WCF Certification Exam
335
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
values, either System.ServiceModel.ImpersonationOption.Required or
System.ServiceModel.ImpersonationOption.Allowed, as shown in the following example.
Note:
When a service has higher credentials than the remote client, the credentials of the service are used if
the Impersonation property is set to Allowed. That is, if a low-privileged user provides its credentials, a
higher-privileged service executes the method with the credentials of the service, and can use resources
that the low-privileged user would otherwise not be able to use.
C#
[ServiceContract]
publicinterface IHelloContract
{
[OperationContract]
string Hello(string message);
}
publicclass HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
publicstring Hello(string message)
{
return"hello";
}
}

The WCF infrastructure can impersonate the caller only if the caller is authenticated with
credentials that can be mapped to a Windows user account. If the service is configured to
authenticate using a credential that cannot be mapped to a Windows account, the service method
is not executed.
Note:
On Windows XP, impersonation fails if a stateful SCT is created, resulting in an
InvalidOperationException. For more information, see Unsupported Scenarios.
Impersonation in a Service Method: Imperative Model
Sometimes a caller does not need to impersonate the entire service method to function, but for
only a portion of it. In this case, obtain the Windows identity of the caller inside the service
method and imperatively perform the impersonation. Do this by using the WindowsIdentity
property of the ServiceSecurityContext to return an instance of the WindowsIdentity class and
calling the Impersonate method before using the instance.
Note:
Be sure to use the Visual Basic Using statement or the C# using statement to automatically revert the
impersonation action. If you do not use the statement, or if you use a programming language other than
Visual Basic or C#, be sure to revert the impersonation level. Failure to do this can form the basis for
denial of service and elevation of privilege attacks.
C#
publicclass HelloService : IHelloService
{
[OperationBehavior]
Resource Links for 70-513 WCF Certification Exam
336
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
publicstring Hello(string message)
{
WindowsIdentity callerWindowsIdentity =
ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
thrownew InvalidOperationException
("The caller cannot be mapped to a WindowsIdentity");
}
using (callerWindowsIdentity.Impersonate())
{
// Access a file as the caller.
}
return"Hello";
}
}
Impersonation for All Service Methods
In some cases, you must perform all the methods of a service in the callers context. Instead of
explicitly enabling this feature on a per-method basis, use the ServiceAuthorizationBehavior. As
shown in the following code, set the ImpersonateCallerForAllOperations property to true. The
ServiceAuthorizationBehavior is retrieved from the collections of behaviors of the ServiceHost
class. Also note that the Impersonation property of the OperationBehaviorAttribute applied to
each method must also be set to either Allowed or Required.
C#
// Code to create a ServiceHost not shown.
ServiceAuthorizationBehavior MyServiceAuthoriationBehavior =
serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
MyServiceAuthoriationBehavior.ImpersonateCallerForAllOperations = true;
The following table describes WCF behavior for all possible combinations of
ImpersonationOption and ImpersonateCallerForAllServiceOperations.
ImpersonationOption ImpersonateCallerForAllServiceOperations Behavior
Required n/a WCF impersonates the caller
Allowed false
WCF does not impersonate the
caller
Allowed true WCF impersonates the caller
NotAllowed false
WCF does not impersonate the
caller
NotAllowed true
Disallowed. (An
InvalidOperationException is
thrown.)
Impersonation Level Obtained from Windows Credentials
and Cached Token Impersonation
In some scenarios the client has partial control over the level of impersonation the service
performs when a Windows client credential is used. One scenario occurs when the client
specifies an Anonymous impersonation level. The other occurs when performing impersonation
with a cached token. This is done by setting the AllowedImpersonationLevel property of the
Resource Links for 70-513 WCF Certification Exam
337
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
WindowsClientCredential class, which is accessed as a property of the generic ChannelFactory
class.
Note:
Specifying an impersonation level of Anonymous causes the client to log on to the service anonymously.
The service must therefore allow anonymous logons, regardless of whether impersonation is performed.
The client can specify the impersonation level as Anonymous, Identification, Impersonation, or
Delegation. Only a token at the specified level is produced, as shown in the following code.
C#
ChannelFactory<IEcho> cf = new ChannelFactory<IEcho>("EchoEndpoint");
cf.Credentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
The following table specifies the impersonation level the service obtains when impersonating
from a cached token.
AllowedImpersonationLevel
value
Service has
SeImpersonatePrivilege
Service and client
are capable of
delegation
Cached token
ImpersonationLevel
Anonymous Yes n/a Impersonation
Anonymous No n/a Identification
Identification n/a n/a Identification
Impersonation Yes n/a Impersonation
Impersonation No n/a Identification
Delegation Yes Yes Delegation
Delegation Yes No Impersonation
Delegation No n/a Identification
Impersonation Level Obtained from User Name Credentials
and Cached Token Impersonation
By passing the service its user name and password, a client enables WCF to log on as that user,
which is equivalent to setting the AllowedImpersonationLevel property to Delegation. (The
AllowedImpersonationLevel is available on the WindowsClientCredential and
HttpDigestClientCredential classes.) The following table provides the impersonation level
obtained when the service receives user name credentials.
AllowedImpersonationLevel
Service has
SeImpersonatePrivilege
Service and client
are capable of
delegation
Cached token
ImpersonationLevel
n/a Yes Yes Delegation
n/a Yes No Impersonation
n/a No n/a Identification
Impersonation Level Obtained from S4U-Based
Impersonation
Resource Links for 70-513 WCF Certification Exam
338
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Service has
SeTcbPrivilege
Service has
SeImpersonatePrivilege
Service and client are
capable of delegation
Cached token
ImpersonationLevel
Yes Yes n/a Impersonation
Yes No n/a Identification
No n/a n/a Identification
Mapping a Client Certificate to a Windows Account
It is possible for a client to authenticate itself to a service using a certificate, and to have the
service map the client to the an existing account through Active Directory. The following XML
shows how to configure the service to map the certificate:
XML
<behaviors>
<serviceBehaviors>
<behaviorname="MapToWindowsAccount">
<serviceCredentials>
<clientCertificate>
<authenticationmapClientCertificateToWindowsAccount="true" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
The following code shows how to configure the service.
// Create a binding that sets a certificate as the client credential type.
WSHttpBinding b = new WSHttpBinding();
b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
// Create a service host that maps the certificate to a Windows account.
Uri httpUri = new Uri("http://localhost/Calculator");
ServiceHost sh = new ServiceHost(typeof(HelloService), httpUri);
sh.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindows
Account = true;
Delegation
To delegate to a back-end service, a service must perform Kerberos multi-leg (SSPI without
NTLM fallback) or Kerberos direct authentication to the back-end service using the clients
Windows identity. To delegate to a back-end service, create a ChannelFactory and a channel,
and then communicate through the channel while impersonating the client. With this form of
delegation, the distance at which the back-end service can be located from the front-end service
depends on the impersonation level achieved by the front-end service. When the impersonation
level is Impersonation, the front-end and back-end services must be running on the same
machine. When the impersonation level is Delegation, the front-end and back-end services can
be on separate machines or on the same machine. Enabling delegation-level impersonation
requires that Windows domain policy be configured to permit delegation. For more information
about configuring Active Directory for delegation support, see Enabling Delegated
Authentication.
Note:
When a client authenticates to the front-end service using a user name and password that correspond
to a Windows account on the back-end service, the front-end service can authenticate to the back-end
Resource Links for 70-513 WCF Certification Exam
339
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
service by reusing the clients user name and password. This is a particularly powerful form of identity
flow, because passing user name and password to the back-end service enables the back-end service to
perform impersonation, but it does not constitute delegation because Kerberos is not used. Active
Directory controls on delegation do not apply to user name and password authentication.
Delegation Ability as a Function of Impersonation Level
Impersonation
level
Service can perform cross-process
delegation
Service can perform cross-machine
delegation
Identification No No
Impersonation Yes No
Delegation Yes Yes
The following code example demonstrates how to use delegation.
C#
publicclass HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
publicstring Hello(string message)
{
WindowsIdentity callerWindowsIdentity =
ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
thrownew InvalidOperationException
("The caller cannot be mapped to a Windows identity.");
}
using (callerWindowsIdentity.Impersonate())
{
EndpointAddress backendServiceAddress = new
EndpointAddress("http://localhost:8000/ChannelApp");
// Any binding that performs Windows authentication of the client can be
used.
ChannelFactory<IHelloService> channelFactory = new
ChannelFactory<IHelloService>(new NetTcpBinding(), backendServiceAddress);
IHelloService channel = channelFactory.CreateChannel();
return channel.Hello(message);
}
}
}
How to Configure an Application to Use Constrained Delegation
Before you can use constrained delegation, the sender, receiver, and the domain controller must
be configured to do so. The following procedure lists the steps that enable constrained
delegation. For details about the differences between delegation and constrained delegation, see
the portion of Windows Server 2003 Kerberos Extensions that discusses constrained discussion.
1. On the domain controller, clear the Account is sensitive and cannot be delegated check box for the
account under which the client application is running.
2. On the domain controller, select the Account is trusted for delegation check box for the account under
which the client application is running.
3. On the domain controller, configure the middle tier computer so that it is trusted for delegation, by
clicking the Trust computer for delegation option.
Resource Links for 70-513 WCF Certification Exam
340
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
4. On the domain controller, configure the middle tier computer to use constrained delegation, by clicking
the Trust this computer for delegation to specified services only option.
For more detailed instructions about configuring constrained delegation, see the following topics
on MSDN:
Troubleshooting Kerberos Delegation
Kerberos Protocol Transition and Constrained Delegation

Implement Impersonation.This objective may include but is not limited to: configuration and
code; configuring WCF-specific Internet Information Services (IIS) impersonation properties;
configuring impersonation options; operation-based and service-based
Delegation and Impersonation with WCF
.NET Framework 3.5
Impersonation is a common technique that services use to restrict client access to a service
domain's resources. Service domain resources can either be machine resources, such as local files
(impersonation), or a resource on another machine, such as a file share (delegation). For a sample
application, see Impersonating the Client Sample. For an example of how to use impersonation,
see How to: Impersonate a Client on a Service.
Note:
Be aware that when impersonating a client on a service, the service runs with the client's credentials,
which may have higher privileges than the server process.
Overview
Typically, clients call a service to have the service perform some action on the clients behalf.
Impersonation allows the service to act as the client while performing the action. Delegation
allows a front-end service to forward the clients request to a back-end service in such a way that
the back-end service can also impersonate the client. Impersonation is most commonly used as a
way of checking whether a client is authorized to perform a particular action, while delegation is
a way of flowing impersonation capabilities, along with the clients identity, to a back-end
service. Delegation is a Windows domain feature that can be used when Kerberos-based
authentication is performed. Delegation is distinct from identity flow and, because delegation
transfers the ability to impersonate the client without possession of the clients password, it is a
much higher privileged operation than identity flow.
Both impersonation and delegation require that the client have a Windows identity. If a client
does not possess a Windows identity, then the only option available is to flow the clients
identity to the second service.
Impersonation Basics
Windows Communication Foundation (WCF) supports impersonation for a variety of client
credentials. This topic describes service model support for impersonating the caller during the
implementation of a service method. Also discussed are common deployment scenarios
involving impersonation and SOAP security and WCF options in these scenarios.
This topic focuses on impersonation and delegation in WCF when using SOAP security. You can
also use impersonation and delegation with WCF when using transport security, as described in
Using Impersonation with Transport Security.
Resource Links for 70-513 WCF Certification Exam
341
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Two Methods
WCF SOAP security has two distinct methods for performing impersonation. The method used
depends on the binding. One is impersonation from a Windows token obtained from the Security
Support Provider Interface (SSPI) or Kerberos authentication, which is then cached on the
service. The second is impersonation from a Windows token obtained from the Kerberos
extensions, collectively called Service-for-User (S4U).
Cached Token Impersonation
You can perform cached-token impersonation with the following:
WSHttpBinding, WSDualHttpBinding, and NetTcpBinding with a Windows client credential.
BasicHttpBinding with a BasicHttpSecurityMode set to the TransportWithMessageCredential credential,
or any other standard binding where the client presents a user name credential that the service can map
to a valid Windows account.
Any CustomBinding that uses a Windows client credential with the requireCancellation set to true. (The
property is available on the following classes: SecureConversationSecurityTokenParameters,
SslSecurityTokenParameters, and SspiSecurityTokenParameters.) If a secure conversation is used on the
binding, it must also have the requireCancellation property set to true.
Any CustomBinding where the client presents a user name credential. If secure conversation is used on
the binding, it must also have the requireCancellation property set to true.
S4U-Based Impersonation
You can perform S4U-based impersonation with the following:
WSHttpBinding, WSDualHttpBinding, and NetTcpBinding with a certificate client credential that the
service can map to a valid Windows account.
Any CustomBinding that uses a Windows client credential with the requireCancellation property set to
false.
Any CustomBinding that uses a user name or Windows client credential and secure conversation with
the requireCancellation property set to false.
The extent to which the service can impersonate the client depends on the privileges the service
account holds when it attempts impersonation, the type of impersonation used, and possibly the
extent of impersonation the client permits.
Note:
When the client and service are running on the same computer and the client is running under a system
account (for example, Local System or Network Service), the client cannot be impersonated when a
secure session is established with stateful Security Context tokens. A Windows Form or console
application typically runs under the currently logged-in account, so that account can be impersonated by
default. However, when the client is an ASP.NET page and that page is hosted in IIS 6.0 or IIS 7.0, then
the client does run under the Network Service account by default. All of the system-provided bindings
that support secure sessions use a stateless security context token (SCT) by default. However, if the
client is an ASP.NET page, and secure sessions with stateful SCTs are used, the client cannot be
impersonated. For more information about using stateful SCTs in a secure session, see How to: Create a
Stateful Security Context Token for a Secure Session.
Impersonation in a Service Method: Declarative Model
Most impersonation scenarios involve executing the service method in the caller context. WCF
provides an impersonation feature that makes this easy to do by allowing the user to specify the
Resource Links for 70-513 WCF Certification Exam
342
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
impersonation requirement in the OperationBehaviorAttribute attribute. For example, in the
following code, the WCF infrastructure impersonates the caller before executing the Hello
method. Any attempt to access native resources inside the Hello method succeed only if the
access control list (ACL) of the resource allows the caller access privileges. To enable
impersonation, set the Impersonation property to one of the ImpersonationOption enumeration
values, either System.ServiceModel.ImpersonationOption.Required or
System.ServiceModel.ImpersonationOption.Allowed, as shown in the following example.
Note:
When a service has higher credentials than the remote client, the credentials of the service are used if
the Impersonation property is set to Allowed. That is, if a low-privileged user provides its credentials, a
higher-privileged service executes the method with the credentials of the service, and can use resources
that the low-privileged user would otherwise not be able to use.
C#
[ServiceContract]
publicinterface IHelloContract
{
[OperationContract]
string Hello(string message);
}
publicclass HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
publicstring Hello(string message)
{
return"hello";
}
}
The WCF infrastructure can impersonate the caller only if the caller is authenticated with
credentials that can be mapped to a Windows user account. If the service is configured to
authenticate using a credential that cannot be mapped to a Windows account, the service method
is not executed.
Note:
On Windows XP, impersonation fails if a stateful SCT is created, resulting in an
InvalidOperationException. For more information, see Unsupported Scenarios.
Impersonation in a Service Method: Imperative Model
Sometimes a caller does not need to impersonate the entire service method to function, but for
only a portion of it. In this case, obtain the Windows identity of the caller inside the service
method and imperatively perform the impersonation. Do this by using the WindowsIdentity
property of the ServiceSecurityContext to return an instance of the WindowsIdentity class and
calling the Impersonate method before using the instance.
Note:
Be sure to use the Visual Basic Using statement or the C# using statement to automatically revert the
impersonation action. If you do not use the statement, or if you use a programming language other than
Visual Basic or C#, be sure to revert the impersonation level. Failure to do this can form the basis for
Resource Links for 70-513 WCF Certification Exam
343
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
denial of service and elevation of privilege attacks.
C#
publicclass HelloService : IHelloService
{
[OperationBehavior]
publicstring Hello(string message)
{
WindowsIdentity callerWindowsIdentity =
ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
thrownew InvalidOperationException
("The caller cannot be mapped to a WindowsIdentity");
}
using (callerWindowsIdentity.Impersonate())
{
// Access a file as the caller.
}
return"Hello";
}
}
Impersonation for All Service Methods
In some cases, you must perform all the methods of a service in the callers context. Instead of
explicitly enabling this feature on a per-method basis, use the ServiceAuthorizationBehavior. As
shown in the following code, set the ImpersonateCallerForAllOperations property to true. The
ServiceAuthorizationBehavior is retrieved from the collections of behaviors of the ServiceHost
class. Also note that the Impersonation property of the OperationBehaviorAttribute applied to
each method must also be set to either Allowed or Required.
C#
// Code to create a ServiceHost not shown.
ServiceAuthorizationBehavior MyServiceAuthoriationBehavior =
serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
MyServiceAuthoriationBehavior.ImpersonateCallerForAllOperations = true;
The following table describes WCF behavior for all possible combinations of
ImpersonationOption and ImpersonateCallerForAllServiceOperations.
ImpersonationOption ImpersonateCallerForAllServiceOperations Behavior
Required n/a WCF impersonates the caller
Allowed false
WCF does not impersonate the
caller
Allowed true WCF impersonates the caller
NotAllowed false
WCF does not impersonate the
caller
NotAllowed true
Disallowed. (An
InvalidOperationException is
thrown.)
Resource Links for 70-513 WCF Certification Exam
344
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Impersonation Level Obtained from Windows Credentials
and Cached Token Impersonation
In some scenarios the client has partial control over the level of impersonation the service
performs when a Windows client credential is used. One scenario occurs when the client
specifies an Anonymous impersonation level. The other occurs when performing impersonation
with a cached token. This is done by setting the AllowedImpersonationLevel property of the
WindowsClientCredential class, which is accessed as a property of the generic ChannelFactory
class.
Note:
Specifying an impersonation level of Anonymous causes the client to log on to the service anonymously.
The service must therefore allow anonymous logons, regardless of whether impersonation is performed.
The client can specify the impersonation level as Anonymous, Identification, Impersonation, or
Delegation. Only a token at the specified level is produced, as shown in the following code.
C#
ChannelFactory<IEcho> cf = new ChannelFactory<IEcho>("EchoEndpoint");
cf.Credentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
The following table specifies the impersonation level the service obtains when impersonating
from a cached token.
AllowedImpersonationLevel
value
Service has
SeImpersonatePrivilege
Service and client
are capable of
delegation
Cached token
ImpersonationLevel
Anonymous Yes n/a Impersonation
Anonymous No n/a Identification
Identification n/a n/a Identification
Impersonation Yes n/a Impersonation
Impersonation No n/a Identification
Delegation Yes Yes Delegation
Delegation Yes No Impersonation
Delegation No n/a Identification
Impersonation Level Obtained from User Name Credentials
and Cached Token Impersonation
By passing the service its user name and password, a client enables WCF to log on as that user,
which is equivalent to setting the AllowedImpersonationLevel property to Delegation. (The
AllowedImpersonationLevel is available on the WindowsClientCredential and
HttpDigestClientCredential classes.) The following table provides the impersonation level
obtained when the service receives user name credentials.
AllowedImpersonationLevel
Service has
SeImpersonatePrivilege
Service and client
are capable of
delegation
Cached token
ImpersonationLevel
Resource Links for 70-513 WCF Certification Exam
345
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
n/a Yes Yes Delegation
n/a Yes No Impersonation
n/a No n/a Identification
Impersonation Level Obtained from S4U-Based
Impersonation
Service has
SeTcbPrivilege
Service has
SeImpersonatePrivilege
Service and client are
capable of delegation
Cached token
ImpersonationLevel
Yes Yes n/a Impersonation
Yes No n/a Identification
No n/a n/a Identification
Mapping a Client Certificate to a Windows Account
It is possible for a client to authenticate itself to a service using a certificate, and to have the
service map the client to the an existing account through Active Directory. The following XML
shows how to configure the service to map the certificate:
XML
<behaviors>
<serviceBehaviors>
<behaviorname="MapToWindowsAccount">
<serviceCredentials>
<clientCertificate>
<authenticationmapClientCertificateToWindowsAccount="true" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
The following code shows how to configure the service.
// Create a binding that sets a certificate as the client credential type.
WSHttpBinding b = new WSHttpBinding();
b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
// Create a service host that maps the certificate to a Windows account.
Uri httpUri = new Uri("http://localhost/Calculator");
ServiceHost sh = new ServiceHost(typeof(HelloService), httpUri);
sh.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindows
Account = true;
Delegation
To delegate to a back-end service, a service must perform Kerberos multi-leg (SSPI without
NTLM fallback) or Kerberos direct authentication to the back-end service using the clients
Windows identity. To delegate to a back-end service, create a ChannelFactory and a channel,
and then communicate through the channel while impersonating the client. With this form of
delegation, the distance at which the back-end service can be located from the front-end service
depends on the impersonation level achieved by the front-end service. When the impersonation
level is Impersonation, the front-end and back-end services must be running on the same
machine. When the impersonation level is Delegation, the front-end and back-end services can
be on separate machines or on the same machine. Enabling delegation-level impersonation
Resource Links for 70-513 WCF Certification Exam
346
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
requires that Windows domain policy be configured to permit delegation. For more information
about configuring Active Directory for delegation support, see Enabling Delegated
Authentication.
Note:
When a client authenticates to the front-end service using a user name and password that correspond
to a Windows account on the back-end service, the front-end service can authenticate to the back-end
service by reusing the clients user name and password. This is a particularly powerful form of identity
flow, because passing user name and password to the back-end service enables the back-end service to
perform impersonation, but it does not constitute delegation because Kerberos is not used. Active
Directory controls on delegation do not apply to user name and password authentication.
Delegation Ability as a Function of Impersonation Level
Impersonation
level
Service can perform cross-process
delegation
Service can perform cross-machine
delegation
Identification No No
Impersonation Yes No
Delegation Yes Yes
The following code example demonstrates how to use delegation.
C#
publicclass HelloService : IHelloService
{
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
publicstring Hello(string message)
{
WindowsIdentity callerWindowsIdentity =
ServiceSecurityContext.Current.WindowsIdentity;
if (callerWindowsIdentity == null)
{
thrownew InvalidOperationException
("The caller cannot be mapped to a Windows identity.");
}
using (callerWindowsIdentity.Impersonate())
{
EndpointAddress backendServiceAddress = new
EndpointAddress("http://localhost:8000/ChannelApp");
// Any binding that performs Windows authentication of the client can be
used.
ChannelFactory<IHelloService> channelFactory = new
ChannelFactory<IHelloService>(new NetTcpBinding(), backendServiceAddress);
IHelloService channel = channelFactory.CreateChannel();
return channel.Hello(message);
}
}
}
How to Configure an Application to Use Constrained Delegation
Before you can use constrained delegation, the sender, receiver, and the domain controller must
be configured to do so. The following procedure lists the steps that enable constrained
Resource Links for 70-513 WCF Certification Exam
347
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
delegation. For details about the differences between delegation and constrained delegation, see
the portion of Windows Server 2003 Kerberos Extensions that discusses constrained discussion.
1. On the domain controller, clear the Account is sensitive and cannot be delegated check box for the
account under which the client application is running.
2. On the domain controller, select the Account is trusted for delegation check box for the account under
which the client application is running.
3. On the domain controller, configure the middle tier computer so that it is trusted for delegation, by
clicking the Trust computer for delegation option.
4. On the domain controller, configure the middle tier computer to use constrained delegation, by clicking
the Trust this computer for delegation to specified services only option.
For more detailed instructions about configuring constrained delegation, see the following topics
on MSDN:
Troubleshooting Kerberos Delegation
Kerberos Protocol Transition and Constrained Delegation

Implement security auditing.This objective may include but is not limited to: using
serviceSecurityAudit behavior, service auditing, audit log
Auditing Security Events
Applications created with Windows Communication Foundation (WCF) can log security events
(either success, failure, or both) with the auditing feature. The events are written to the Windows
system event log and can be examined using the Event Viewer.
Auditing provides a way for an administrator to detect an attack that has already occurred or is in
progress. In addition, auditing can help a developer to debug security-related problems. For
example, if an error in the configuration of the authorization or checking policy accidentally
denies access to an authorized user, a developer can quickly discover and isolate the cause of this
error by examining the event log.
For more information about WCF security, see Security Overview. For more information about
programming WCF, see Basic WCF Programming.
Audit Level and Behavior
Two levels of security audits exist:
Service authorization level, in which a caller is authorized.
Message level, in which WCF checks for message validity and authenticates the caller.
You can check both audit levels for success or failure, which is known as the audit behavior.
Audit Log Location
Once you determine an audit level and behavior, you (or an administrator) can specify a location
for the audit log. The three choices include: Default, Application, and Security. When you
specify Default, the actual log depends on which system you are using and whether the system
supports writing to the security log. For more information, see the "Operating System" section
later in this topic.
To write to the Security log requires the SeAuditPrivilege. By default, only Local System and
Network Service accounts have this privilege. To manage the Security log functions read and
delete requires the SeSecurityPrivilege. By default, only administrators have this privilege.
Resource Links for 70-513 WCF Certification Exam
348
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
In contrast, authenticated users can read and write to the Application log. Windows XP writes
audit events to the Application log by default. The log can also contain personal information that
is visible to all authenticated users.
Suppressing Audit Failures
Another option during auditing is whether to suppress any audit failure. By default, an audit
failure does not affect an application. If required, however, you can set the option to false, which
causes an exception to be thrown.
Programming Auditing
You can specify auditing behavior either programmatically or through configuration.
Auditing Classes
The following table describes the classes and properties used to program auditing behavior.
Class Description
ServiceSecurityAuditBehavior Enables setting options for auditing as a service behavior.
AuditLogLocation
Enumeration to specify which log to write to. The possible
values are Default, Application, and Security. When you
select Default, the operating system determines the actual log
location. See the "Application or Security Event Log Choice"
section later in this topic.
MessageAuthenticationAuditLevel
Specifies which types of message authentication events are
audited at the message level. The choices are None, Failure,
Success, and SuccessOrFailure.
ServiceAuthorizationAuditLevel
Specifies which types of service authorization events are
audited at the service level. The choices are None, Failure,
Success, and SuccessOrFailure.
SuppressAuditFailure
Specifies what happens to the client request when auditing
fails. For example, when the service attempts to write to the
security log, but does not have SeAuditPrivilege. The
default value of true indicates that failures are ignored, and
the client request is processed normally.
For an example of setting up an application to log audit events, see How to: Audit Windows
Communication Foundation Security Events.
Configuration
You can also use configuration to specify auditing behavior by adding a serviceSecurityAudit
element under the Behaviors element. You must add the element under a Behavior element as
shown in the following code.
<configuration>
<system.serviceModel>
<behaviors>
<behavior>
<! auditLogLocation="Application" or "Security" ->
<serviceSecurityAuditauditLogLocation="Application"
suppressAuditFailure="true"serviceAuthorizationAuditLevel="Failure"
messageAuthenticationAuditLevel="SuccessOrFailure" />
</behavior>
Resource Links for 70-513 WCF Certification Exam
349
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
</behaviors>
</system.serviceModel>
</configuration>
If auditing is enabled and an auditLogLocation is not specified, the default log name is
"Security" log for the platform supporting writing to the Security log; otherwise, it is
"Application" log. Only the Windows Server 2003 and Windows Vista operating systems
support writing to the Security log. For more information, see the "Operating System" section
later in this topic.
Security Considerations
If a malicious user knows that auditing is enabled, that attacker can send invalid messages that
cause audit entries to be written. If the audit log is filled in this manner, the auditing system fails.
To mitigate this, set the SuppressAuditFailure property to true and use the properties of the
Event Viewer to control the auditing behavior. For more information, see the Microsoft Support
article on viewing and managing event logs by using the Event Viewer in Windows XP available
at .Audit events that are written to the Application Log on Windows XP are visible to any
authenticated user.
Choosing Between Application and Security Event Logs
The following tables provide information to help you choose whether to log into the Application
or the Security event log.
Operating System
System
Application
log
Security log
Windows XP SP2 or later Supported Not supported
Windows Server 2003 SP1 and
Windows Vista
Supported
Thread context must possess
SeAuditPrivilege
Other Factors
In addition to the operating system, the following table describes other settings that control the
enablement of logging.
Factor Application log Security log
Audit policy
management
Not applicable.
Along with configuration, the Security log is
also controlled by the local security authority
(LSA) policy. The "Audit object access"
category must also be enabled.
Default user
experience
All authenticated users can write
to the Application log, so no
additional permission step is
needed for application processes.
The application process (context) must have
SeAuditPrivilege.

Managing the Service Instance Life Cycle (13%)
Manage service instances.This objective may include but is not limited to: per call; per session;
single; code and configuration; activation and deactivation; durable services; throttling
Resource Links for 70-513 WCF Certification Exam
350
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Sessions, Instancing, and Concurrency in
Windows Communication Foundation
A session is a correlation of all messages sent between two endpoints. Instancing refers to
controlling the lifetime of user-defined service objects and their related InstanceContext objects.
Concurrency is the term given to the control of the number of threads executing in an
InstanceContext at the same time.This topic describes these settings, how to use them, and the
various interactions between them.
Sessions
When a service contract sets the System.ServiceModel.ServiceContractAttribute.SessionMode
property to System.ServiceModel.SessionMode.Required, that contract is saying that all calls
(that is, the underlying message exchanges that support the calls) must be part of the same
conversation. If a contract specifies that it allows sessions but does not require one, clients can
connect and either establish a session or not. If the session ends and a message is sent over the
same session-based channel an exception is thrown.
WCF sessions have the following main conceptual features:
They are explicitly initiated and terminated by the calling application.
Messages delivered during a session are processed in the order in which they are received.
Sessions correlate a group of messages into a conversation. The meaning of that correlation is an
abstraction. For instance, one session-based channel may correlate messages based on a shared
network connection while another session-based channel may correlate messages based on a
shared tag in the message body. The features that can be derived from the session depend on the
nature of the correlation.
There is no general data store associated with a WCF session.
If you are familiar with the System.Web.SessionState.HttpSessionState class in ASP.NET
applications and the functionality it provides, you might notice the following differences
between that kind of session and WCF sessions:
ASP.NET sessions are always server-initiated.
ASP.NET sessions are implicitly unordered.
ASP.NET sessions provide a general data storage mechanism across requests.
Client applications and service applications interact with sessions in different ways. Client
applications initiate sessions and then receive and process the messages sent within the session.
Service applications can use sessions as an extensibility point to add additional behavior. This is
done by working directly with the InstanceContext or implementing a custom instance context
provider.
Instancing
The instancing behavior (set by using the
System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode property) controls how
the InstanceContext is created in response to incoming messages. By default, each
InstanceContext is associated with one user-defined service object, so (in the default case)
setting the InstanceContextMode property also controls the instancing of user-defined service
objects. The InstanceContextMode enumeration defines the instancing modes.
The following instancing modes are available:
PerCall: A new InstanceContext (and therefore service object) is created for each client request.
Resource Links for 70-513 WCF Certification Exam
351
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
PerSession: A new InstanceContext (and therefore service object) is created for each new client
session and maintained for the lifetime of that session (this requires a binding that supports
sessions).
Single: A single InstanceContext (and therefore service object) handles all client requests for
the lifetime of the application.
The following code example shows the default InstanceContextMode value, PerSession being
explicitly set on a service class.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorInstance
{

}
And while the System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode
property controls how often the InstanceContext is released, the
System.ServiceModel.OperationBehaviorAttribute.ReleaseInstanceMode and
System.ServiceModel.ServiceBehaviorAttribute.ReleaseServiceInstanceOnTransactionComplete
properties control when the service object is released.
Well-Known Singleton Services
One variation on single instance service objects is sometimes useful: you can create a service
object yourself and create the service host using that object. To do so, you must also set the
System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode property to Single or
an exception is thrown when the service host is opened.Use the
System.ServiceModel.ServiceHost.#ctor(System.Object,System.Uri[]) constructor to create such
a service. It provides an alternative to implementing a custom
System.ServiceModel.Dispatcher.IInstanceContextInitializer when you wish to provide a
specific object instance for use by a singleton service. You can use this overload when your
service implementation type is difficult to construct (for example, if it does not implement a
default parameterless public constructor). Note that when an object is provided to this
constructor, some features related to the Windows Communication Foundation (WCF)
instancing behavior work differently. For example, calling
System.ServiceModel.InstanceContext.ReleaseServiceInstance has no effect when a singleton
object instance is provided. Similarly, any other instance-release mechanism is ignored. The
ServiceHost always behaves as if the
System.ServiceModel.OperationBehaviorAttribute.ReleaseInstanceMode property is set to
System.ServiceModel.ReleaseInstanceMode.None for all operations.
Sharing InstanceContext Objects
You can also control which sessionful channel or call is associated with which InstanceContext
object by performing that association yourself. For a complete example, see
InstanceContextSharing.
Concurrency
Concurrency is the control of the number of threads active in an InstanceContext at any one
time. This is controlled by using the
System.ServiceModel.ServiceBehaviorAttribute.ConcurrencyMode with the ConcurrencyMode
enumeration.
The following three concurrency modes are available:
Resource Links for 70-513 WCF Certification Exam
352
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Single: Each instance context is allowed to have a maximum of one thread processing messages
in the instance context at a time. Other threads wishing to use the same instance context must
block until the original thread exits the instance context.
Multiple: Each service instance can have multiple threads processing messages concurrently. The
service implementation must be thread-safe to use this concurrency mode.
Reentrant: Each service instance processes one message at a time, but accepts re-entrant
operation calls. The service only accepts these calls when it is calling out through a WCF client
object.
Note:
Understanding and developing code that safely uses more than one thread can be difficult to
write successfully. Before using Multiple or Reentrant values, ensure that your service is
properly designed for these modes. For more information, see ConcurrencyMode.
The use of concurrency is related to the instancing mode. In PerCall instancing, concurrency is
not relevant, because each message is processed by a new InstanceContext and, therefore, never
more than one thread is active in the InstanceContext.
The following code example demonstrates setting the ConcurrencyMode property to Multiple.
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.Single)]
public class CalculatorService : ICalculatorConcurrency
{

}
Sessions Interact with InstanceContext Settings
Sessions and InstanceContext interact depending upon the combination of the value of the
SessionMode enumeration in a contract and the
System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode property on the
service implementation, which controls the association between channels and specific service
objects.The following table shows the result of an incoming channel either supporting sessions or
not supporting sessions given a service's combination of the values of the
System.ServiceModel.ServiceContractAttribute.SessionMode property and the
System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode property.
InstanceContextMode
value
Required Allowed NotAllowed
PerCall
Behavior with
sessionful channel:
A session and
InstanceContext for
each call.
Behavior with
sessionless channel:
An exception is
thrown.
Behavior with
sessionful channel: A
session and
InstanceContext for
each call.
Behavior with
sessionless channel: An
InstanceContext for
each call.
Behavior with sessionful
channel: An exception is
thrown.
Behavior with
sessionless channel: An
InstanceContext for
each call.
PerSession
Behavior with
sessionful channel:
A session and
Behavior with
sessionful channel: A
session and
Behavior with sessionful
channel: An exception is
thrown.
Resource Links for 70-513 WCF Certification Exam
353
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
InstanceContext for
each channel.
Behavior with
sessionless channel:
An exception is
thrown.
InstanceContext for
each channel.
Behavior with
sessionless channel: An
InstanceContext for
each call.
Behavior with
sessionless channel: An
InstanceContext for
each call.
Single
Behavior with
sessionful channel:
A session and one
InstanceContext for
all calls.
Behavior with
sessionless channel:
An exception is
thrown.
Behavior with
sessionful channel: A
session and
InstanceContext for
the created or user-
specified singleton.
Behavior with
sessionless channel: An
InstanceContext for
the created or user-
specified singleton.
Behavior with sessionful
channel: An exception is
thrown.
Behavior with
sessionless channel: An
InstanceContext for
each created singleton or
for the user-specified
singleton.

Manage sessions.This objective may include but is not limited to: code and configuration;
session management attributes; throttling; reliable sessions; transport-level and application-level
sessions; invoking a callback contract
Using Sessions
In Windows Communication Foundation (WCF) applications, a session correlates a group of
messages into a conversation. WCF sessions are different than the session object available in
ASP.NET applications, support different behaviors, and are controlled in different ways. This
topic describes the features that sessions enable in WCF applications and how to use them.
Sessions in Windows Communication Foundation
Applications
When a service contract specifies that it requires a session, that contract is specifying that all
calls (that is, the underlying message exchanges that support the calls) must be part of the same
conversation. If a contract specifies that it allows sessions but does not require one, clients can
connect and either establish a session or not establish a session. If the session ends and a message
is sent through the same channel an exception is thrown.
WCF sessions have the following main conceptual features:
They are explicitly initiated and terminated by the calling application.
Messages delivered during a session are processed in the order in which they are received.
Sessions correlate a group of messages into a conversation. The meaning of that correlation is an
abstraction. For instance, one session-based channel may correlate messages based on a shared
network connection while another session-based channel may correlate messages based on a
shared tag in the message body. The features that can be derived from the session depend on the
nature of the correlation.
There is no general data store associated with a WCF session.
Resource Links for 70-513 WCF Certification Exam
354
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
If you are familiar with the System.Web.SessionState.HttpSessionState class in ASP.NET
applications and the functionality it provides, you might notice the following differences
between that kind of session and WCF sessions:
ASP.NET sessions are always server-initiated.
ASP.NET sessions are implicitly unordered.
ASP.NET sessions provide a general data storage mechanism across requests.
This topic describes:
The default execution behavior when using session-based bindings in the service model layer.
The types of features that the WCF session-based, system-provided bindings provide.
How to create a contract that declares a session requirement.
How to understand and control the creation and termination of the session and the relationship of
the session to the service instance.
Default Execution Behavior Using Sessions
A binding that attempts to initiate a session is called a session-based binding. Service contracts
specify that they require, permit, or refuse session-based bindings by setting the
System.ServiceModel.ServiceContractAttribute.SessionMode property on the service contract
interface (or class) to one of the System.ServiceModel.SessionMode enumeration values. By
default, the value of this property is Allowed, which means that if a client uses a session-based
binding with a WCF service implementation, the service establishes and uses the session
provided.
When a WCF service accepts a client session, the following features are enabled by default:
1. All calls between a WCF client object are handled by the same user-defined service object.
2. In addition to this instancing behavior, different session-based bindings provide additional
features.
System-Provided Session Types
A session-based binding supports the default association of a service object with a particular
session. However, different session-based bindings support different features in addition to
enabling the session-based instancing control previously described.
WCF provides the following types of session-based application behavior:
The System.ServiceModel.Channels.SecurityBindingElement supports security-based sessions,
in which both ends of communication have agreed upon a specific secure conversation. For more
information, see Securing Services. For example, the System.ServiceModel.WSHttpBinding
binding, which contains support for both security sessions and reliable sessions, by default uses
only a secure session that encrypts and digitally signs messages.
The System.ServiceModel.NetTcpBinding binding supports TCP/IP-based sessions to ensure
that all messages are correlated by the connection at the socket level.
The System.ServiceModel.Channels.ReliableSessionBindingElement element, which
implements the WS-ReliableMessaging specification, provides support for reliable sessions in
which messages can be configured to be delivered in order and exactly once, enabling
confidence even when messages travel across multiple nodes during the conversation. For more
information, see Reliable Sessions.
The System.ServiceModel.NetMsmqBinding binding provides MSMQ datagram sessions. For
more information, see Queues in Windows Communication Foundation.
Setting the SessionMode property does not specify the type of session the contract requires, only
that it requires one.
Resource Links for 70-513 WCF Certification Exam
355
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Creating a Contract That Requires a Session
Creating a contract that requires a session states that the group of operations that the service
contract declares must all be executed within the same session and that messages must be
delivered in order. To assert the level of session support that a service contract requires, set the
System.ServiceModel.ServiceContractAttribute.SessionMode property on your service
contract interface or class to the value of the System.ServiceModel.SessionMode enumeration
to specify whether the contract:
Requires a session.
Allows a client to establish a session.
Prohibits a session.
Setting the SessionMode property does not, however, specify the type of session-based behavior
the contract requires. It instructs WCF to confirm at runtime that the configured binding (which
creates the communication channel) for the service does, does not, or can establish a session
when implementing a service. Again, the binding can satisfy that requirement with any type of
session-based behavior it choosessecurity, transport, reliable, or some combination. The exact
behavior depends on the System.ServiceModel.SessionMode value selected. If the configured
binding of the service does not conform to the value of SessionMode, an exception is thrown.
Bindings and the channels they create that support sessions are said to be session-based.
The following service contract specifies that all operations in the ICalculatorSession must be
exchanged within a session. None of the operations returns a value to the caller except the
Equals method. However, the Equals method takes no parameters and, therefore, can only
return a non-zero value inside a session in which data has already been passed to the other
operations. This contract requires a session to function properly. Without a session associated
with a specific client, the service instance has no way of knowing what previous data this client
has sent.
C#
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples",
SessionMode=SessionMode.Required)]
publicinterface ICalculatorSession
{
[OperationContract(IsOneWay=true)]
void Clear();
[OperationContract(IsOneWay = true)]
void AddTo(double n);
[OperationContract(IsOneWay = true)]
void SubtractFrom(double n);
[OperationContract(IsOneWay = true)]
void MultiplyBy(double n);
[OperationContract(IsOneWay = true)]
void DivideBy(double n);
[OperationContract]
double Equals();
}
If a service allows a session, then a session is established and used if the client initiates one;
otherwise, no session is established.
Sessions and Service Instances
If you use the default instancing behavior in WCF, all calls between a WCF client object are
handled by the same service instance. Therefore, at the application level, you can think of a
Resource Links for 70-513 WCF Certification Exam
356
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
session as enabling application behavior similar to local call behavior. For example, when you
create a local object:
A constructor is called.
All subsequent calls made to the WCF client object reference are processed by the same object
instance.
A destructor is called when the object reference is destroyed.
Sessions enable a similar behavior between clients and services as long as the default service
instance behavior is used. If a service contract requires or supports sessions, one or more contract
operations can be marked as initiating or terminating a session by setting the IsInitiating and
IsTerminating properties. Initiating operations are those that must be called as the first operation
of a new session. Non-initiating operations can be called only after at least one initiating
operation has been called. You can therefore create a kind of session constructor for your service
by declaring initiating operations designed to take input from clients appropriate to the beginning
of the service instance. (The state is associated with the session, however, and not the service
object.)Terminating operations, conversely, are those that must be called as the last message in
an existing session. In the default case, WCF recycles the service object and its context after the
session with which the service was associated is closed. You can, therefore, create a kind of
destructor by declaring terminating operations designed to perform a function appropriate to the
end of the service instance.
Note:
Although the default behavior bears a resemblance to local constructors and destructors, it is
only a resemblance. Any WCF service operation can be an initiating or terminating operation, or
both at the same time. In addition, in the default case, initiating operations can be called any
number of times in any order after the first one is called; no additional sessions are created once
the session is established and associated with an instance unless you explicitly specify that the
lifetime of the service instance (represented at runtime by a
System.ServiceModel.InstanceContext object). Finally, the state is associated with the session
and not the service object.
For example, the ICalculatorSession contract used in the preceding example requires that the
WCF client object first call the Clear operation prior to any other operation and that the session
with this WCF client object should terminate when it calls the Equals operation. The following
code example shows a contract that enforces these requirements. Clear must be called first to
initiate a session, and that session ends when Equals is called.
C#
ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples",
SessionMode=SessionMode.Required)]
publicinterface ICalculatorSession
{
[OperationContract(IsOneWay=true, IsInitiating=true, IsTerminating=false)]
void Clear();
[OperationContract(IsOneWay =true,IsInitiating = false,IsTerminating =false)]
void AddTo(double n);
[OperationContract(IsOneWay=true,IsInitiating =false,IsTerminating = false)]
void SubtractFrom(double n);
[OperationContract(IsOneWay =true,IsInitiating =false,IsTerminating =false)]
void MultiplyBy(double n);
[OperationContract(IsOneWay =true,IsInitiating=false,IsTerminating = false)]
Resource Links for 70-513 WCF Certification Exam
357
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
void DivideBy(double n);
[OperationContract(IsInitiating = false, IsTerminating = true)]
double Equals();
}

Services do not start sessions with clients. In WCF client applications, a direct relationship exists
between the lifetime of the session-based channel and the lifetime of the session itself. As such,
clients create new sessions by creating new session-based channels and tear down existing
sessions by closing session-based channels gracefully. A client starts a session with a service
endpoint by calling one of the following:
System.ServiceModel.ICommunicationObject.Open on the channel returned by a call to
System.ServiceModel.ChannelFactory.CreateChannel.
System.ServiceModel.ClientBase.Open on the WCF client object generated by the ServiceModel
Metadata Utility Tool (Svcutil.exe).
An initiating operation on either type of WCF client object (by default, all operations are
initiating). When the first operation is called, the WCF client object automatically opens the
channel and initiates a session.
Typically a client ends a session with a service endpoint by calling one of the following:
System.ServiceModel.ICommunicationObject.Close on the channel returned by a call to
System.ServiceModel.ChannelFactory.CreateChannel.
System.ServiceModel.ClientBase.Close on the WCF client object generated by Svcutil.exe.
A terminating operation on either type of WCF client object (by default, no operations are
terminating; the contract must explicitly specify a terminating operation). When the first
operation is called, the WCF client object automatically opens the channel and initiates a session.
For examples, see How to: Create a Service That Requires Sessions as well as the Default
Service Behavior and Instancing samples.
For more information about clients and sessions, see Accessing Services Using a Client.
Sessions Interact with InstanceContext Settings
There is an interaction between the SessionMode enumeration in a contract and the
System.ServiceModel.ServiceBehaviorAttribute.InstanceContextMode property, which controls
the association between channels and specific service objects. For more information, see
Sessions, Instancing, and Concurrency in Windows Communication Foundation.
Sharing InstanceContext Objects
You can also control which session-based channel or call is associated with which
InstanceContext object by performing that association yourself. For a complete example, see
InstanceContextSharing.
Sessions and Streaming
When you have a large amount of data to transfer, the streaming transfer mode in WCF is a
feasible alternative to the default behavior of buffering and processing messages in memory in
their entirety. You may get unexpected behavior when streaming calls with a session-based
binding. All streaming calls are made through a single channel (the datagram channel) that does
not support sessions even if the binding being used is configured to use sessions. If multiple
clients make streaming calls to the same service object over a session-based binding, and the
service object's concurrency mode is set to single and its instance context mode is set to
PerSession, all calls must go through the datagram channel and so only one call is processed at a
Resource Links for 70-513 WCF Certification Exam
358
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
time. One or more clients may then time out. You can work around this issue by either setting the
service object's InstanceContextMode to PerCall or Concurrency to multiple.
Note:
MaxConcurrentSessions have no effect in this case because there is only one "session" available.
Implement transactions.This objective may include but is not limited to: distributed transactions;
transactional queues;transaction flow; configuring transaction binding attributes; WS-
AtomicTransaction (WS-AT); transactional behavior attributes at the service and operation level;
using transactions in code
Windows Communication Foundation
Transactions Overview
Transactions provide a way to group a set of actions or operations into a single indivisible unit of
execution. A transaction is a collection of operations with the following properties:
Atomicity. This ensures that either all of the updates completed under a specific transaction are
committed and made durable or they are all aborted and rolled back to their previous state.
Consistency. This guarantees that the changes made under a transaction represent a
transformation from one consistent state to another. For example, a transaction that transfers
money from a checking account to a savings account does not change the amount of money in
the overall bank account.
Isolation. This prevents a transaction from observing uncommitted changes belonging to other
concurrent transactions. Isolation provides an abstraction of concurrency while ensuring one
transaction cannot have an unexpected impact on the execution of another transaction.
Durability. This means that once committed, updates to managed resources (such as a database
record) will be persistent in the face of failures.
Windows Communication Foundation (WCF) provides a rich set of features that enable you to
create distributed transactions in your Web service application.
WCF implements support for the WS-AtomicTransaction (WS-AT) protocol that enables WCF
applications to flow transactions to interoperable applications, such as interoperable Web
services built using third-party technology. WCF also implements support for the OLE
Transactions protocol, which can be used in scenarios where you do not need interop
functionality to enable transaction flow.
You can use an application configuration file to configure bindings to enable or disable
transaction flow, as well as set the desired transaction protocol on a binding. In addition, you can
set transaction time-outs at the service level using the configuration file. For more information,
see Enabling Transaction Flow.
Transaction attributes in the System.ServiceModel namespace allow you to do the following:
Configure transaction time-outs and isolation-level filtering using the ServiceBehaviorAttribute
attribute.
Enable transactions functionality and configure transaction completion behavior using the
OperationBehaviorAttribute attribute.
Use the ServiceContractAttribute and OperationContractAttribute attributes on a contract method
to require, allow or deny transaction flow.
For more information, see ServiceModel Transaction Attributes.
Resource Links for 70-513 WCF Certification Exam
359
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Transaction Models
This topic describes the relationship between the transaction programming models and the
infrastructure components Microsoft provides.
When using transactions in Windows Communication Foundation (WCF), it is important to
understand that you are not selecting between different transactional models, but rather operating
at different layers of an integrated and consistent model.
The following sections describe the three primary transaction components.
Windows Communication Foundation Transactions
The transaction support in WCF allows you write transactional services. In addition, with its
support for the WS-AtomicTransaction (WS-AT) protocol, applications can flow transactions to
Web services built using either WCF or third-party technology.
In a WCF service or application, WCF transaction features provide attributes and configuration
for declaratively specifying how and when the infrastructure should create, flow, and
synchronize transactions.
System.Transactions Transactions
The System.Transactions namespace provides both an explicit programming model based on the
Transaction class, as well as an implicit programming model using the TransactionScope class,
in which the infrastructure automatically manages transactions.
For more information about how to create a transactional application using these two models, see
Writing a Transactional Application.
In a WCF service or application, System.Transactions provides the programming model for
creating transactions within a client application and for explicitly interacting with a transaction,
when required, within a service.
MSDTC Transactions
The Microsoft Distributed Transaction Coordinator (MSDTC) is a transaction manager that
provides support for distributed transactions.
For more information, see the DTC Programmer's Reference.
In a WCF service or application, MSDTC provides the infrastructure for the coordination of
transactions created within a client or service.
Using WS-AtomicTransaction
WS-AtomicTransaction (WS-AT) is an interoperable transaction protocol. It enables you to flow
distributed transactions by using Web service messages, and coordinate in an interoperable
manner between heterogeneous transaction infrastructures. WS-AT uses the two-phase commit
protocol to drive an atomic outcome between distributed applications, transaction managers, and
resource managers.
The WS-AT implementation Windows Communication Foundation (WCF) provides includes a
protocol service built into the Microsoft Distributed Transaction Coordinator (MSDTC)
transaction manager. Using WS-AT, WCF applications can flow transactions to other
applications, including interoperable Web services built using third-party technology.
When flowing a transaction between a client application and a server application, the transaction
protocol used is determined by the binding that the server exposes on the endpoint the client
selected. Some WCF system-provided bindings default to specifying the
Resource Links for 70-513 WCF Certification Exam
360
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
OleTransactionsprotocol as the transaction propagation format, while others default to
specifying WS-AT. You can also programmatically modify the choice of transaction protocol
inside a given binding.
The choice of protocol influences:
The format of the message headers used to flow the transaction from client to server.
The network protocol used to run the two-phase commit protocol between the client's transaction
manager and the server's transaction, in order to resolve the outcome of the transaction.
If the server and client are written using WCF, you do not need to use WS-AT. Instead, you can
use the default settings of NetTcpBinding with the TransactionFlow attribute enabled, which
will use the OleTransactions protocol instead. For more information, see <netTcpBinding>.
Otherwise, if you are flowing transactions to Web services built on third-party technologies, you
must use WS-AT.
Transactional Support in
System.ServiceModel
The topics in this section describe the transactional functionalities Windows Communication
Foundation (WCF) provides.
ServiceModel Transaction Attributes
Windows Communication Foundation (WCF) provides properties on three standard
System.ServiceModel attributes that enable you to configure the behavior of transactions for a
WCF service:
TransactionFlowAttribute
ServiceBehaviorAttribute
OperationBehaviorAttribute
TransactionFlowAttribute
The TransactionFlowAttribute attribute specifies the willingness of an operation in a service
contract to accept incoming transactions from a client. The attribute provides this control with
the following property: Transactions use the TransactionFlowOption enumeration to specify
whether an incoming transaction is Mandatory, Allowed, or NotAllowed.
This is the only attribute that relates service operations to external interactions with a client. The
attributes described in the following sections relate to the use of transactions within the execution
of the operation.
ServiceBehaviorAttribute
The ServiceBehaviorAttribute attribute specifies the internal execution behavior of a service
contract implementation. Transaction-specific properties of this attribute include:
TransactionAutoCompleteOnSessionClose specifies whether to complete an uncompleted
transaction when the session closes. The default value for this property is false. If this property is
true, and the incoming session was gracefully shut down instead of closing due to network or
client faults, any uncompleted transaction is successfully completed. Otherwise, if this property
is false or if the session was not gracefully closed, any uncompleted transaction is rolled back
when the session closes. If this property is true, the incoming channel must be session-based.
ReleaseServiceInstanceOnTransactionComplete specifies whether the underlying service
instance is released when a transaction completes. The default value for this property is true.
Resource Links for 70-513 WCF Certification Exam
361
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The next inbound message causes a new underlying instance to be created, discarding any per-
transaction state that the previous instance might have held. Releasing a service instance is an
internal action the service takes and has no impact on any existing connections or sessions that
clients might have established. This functionality is equivalent to the just-in-time activation
feature COM+ provides. If the property is true, ConcurrencyMode must be equal to Single.
Otherwise, the service throws an invalid configuration validation exception during startup.
TransactionIsolationLevel specifies the isolation level to use for transactions within the service;
this property takes one of the IsolationLevel values. If the local isolation level property is
anything other than Unspecified, the isolation level of an incoming transaction must match the
setting of this local property. Otherwise, the incoming transaction is rejected, and a fault is sent
back to the client. If TransactionScopeRequired is true, and no transaction is flowed, this
property determines the IsolationLevel value to use for the locally created transaction. If
IsolationLevel is set to Unspecified, IsolationLevelSerializable is used.
TransactionTimeout specifies the time period within which a new transaction created at the
service must complete. If this time is reached and the transaction has not been completed, it will
abort. The TimeSpan is used as the TransactionScope time-out for any operations that have
TransactionScopeRequired set to true and for which a new transaction was created. The time-
out is the maximum allowed duration from the creation of the transaction to the completion of
phase 1 in the two-phase commit protocol. The time-out value used is always the lower value
between the TransactionTimeout property and the transactionTimeout configuration setting.
OperationBehaviorAttribute
The OperationBehaviorAttribute attribute specifies the behaviors of the methods in the service
implementation. You can use it to indicate the operation's specific execution behavior. Properties
of this attribute do not affect the Web Service Description Language (WSDL) description of the
service contract, and are purely elements of the WCF programming model that enable common
features that developers otherwise have to implement themselves.
This attribute has the following transaction-specific properties:
TransactionScopeRequired specifies whether a method must execute within an active
transaction scope. The default is false. If the OperationBehaviorAttribute attribute is not set
for a method, it also implies that the method will not execute in a transaction. If a transaction
scope is not required for an operation, any transaction that is present within the message header
is not activated and remains as an element of the IncomingMessageProperties of the
OperationContext. If a transaction scope is required for an operation, the source for the
transaction is derived from one of the following:
o If a transaction is flowed from the client, the method is executed under a transaction scope
created using that distributed transaction.
o With a queued transport, the transaction used to dequeue the message is used. Note that the
transaction used is not a flowed transaction, in that it was not provided by the original sender of
the message.
o A custom transport can provide a transaction through the use of the
TransportTransactionProperty.
o If none of the above provides an external source for a transaction, a new Transaction instance is
created immediately prior to calling the method.
TransactionAutoComplete specifies whether the transaction in which the method executes is
automatically completed if no unhandled exceptions are thrown. If this property is true, the
Resource Links for 70-513 WCF Certification Exam
362
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
calling infrastructure automatically marks the transaction as "completed" if the user method
returns without throwing an exception. If this property is false, the transaction is attached to the
instance, and is only marked as "completed" if the client calls a subsequent method that is
marked with this property equal to true, or if a subsequent method explicitly calls
SetTransactionComplete. Failure to perform either of these results in the transaction never being
"completed," and the contained work is not committed, unless the
TransactionAutoCompleteOnSessionClose property is set to true. If this property is set to
true, you must use a channel with a session, and the InstanceContextMode must be set to
PerSession.
ServiceModel Transaction Configuration
Windows Communication Foundation (WCF) provides three attributes for configuring
transactions for a service: transactionFlow, transactionProtocol, and transactionTimeout.
Configuring transactionFlow
Most of the predefined bindings WCF provides contain the transactionFlow and
transactionProtocol attributes, so that you can configure the binding to accept incoming
transactions for a specific endpoint using a specific transaction flow protocol. In addition, you
can use the transactionFlow element and its transactionProtocol attribute to build your own
custom binding. For more information about setting the configuration elements, see <binding>
and Windows Communication Foundation Configuration Schema.
The transactionFlow attribute specifies whether transaction flow is enabled for service
endpoints that use the binding.
Configuring transactionProtocol
The transactionProtocol attribute specifies the transaction protocol to use with service
endpoints that use the binding.
The following is an example of a configuration section that configures the specified binding to
support transaction flow, as well as a use the WS-AtomicTransaction protocol.
<netNamedPipeBinding>
<binding name="test" closeTimeout="00:00:10" openTimeout="00:00:20"
receiveTimeout="00:00:30" sendTimeout="00:00:40"
transactionFlow="true" transactionProtocol="WSAtomicTransactionOctober2004"
hostNameComparisonMode="WeakWildcard" maxBufferSize="1001"
maxConnections="123" maxReceivedMessageSize="1000">
</binding>
</netNamedPipeBinding>
Configuring transactionTimeout
You can configure the transactionTimeout attribute for your WCF service in the behavior
element of the configuration file. The following code demonstrates how to do this.
<configuration>
<system.serviceModel>
<behaviors>
<behavior name="NewBehavior" transactionTimeout="00:01:00" /><!-- 1 minute
timeout -->
</behaviors>
</system.serviceModel>
</configuration>
Resource Links for 70-513 WCF Certification Exam
363
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The transactionTimeout attribute specifies the time period within which a new transaction
created at the service must complete. It is used as the TransactionScope time-out for any
operation that establishes a new transaction, and if OperationBehaviorAttribute is applied, the
TransactionScopeRequired property is set to true. The time-out specifies the duration of time
from the creation of the transaction to the completion of phase 1 in the two-phase commit
protocol. If this attribute is set within a service configuration section, you should apply at least
one method of the corresponding service with OperationBehaviorAttribute, in which the
TransactionScopeRequired property is set to true. Note that the time-out value used is the
smaller value between this transactionTimeout configuration setting and any
TransactionTimeout property.
Enabling Transaction Flow
Windows Communication Foundation (WCF) provides highly flexible options for controlling
transaction flow. A service's transaction flow settings can be expressed using a combination of
attributes and configuration.
Transaction Flow Settings
Transaction flow settings are generated for a service endpoint as a result of the intersection of the
following three values:
The TransactionFlowAttribute attribute specified for each method in the service contract.
The TransactionFlow binding property in the specific binding.
The TransactionFlowProtocol binding property in the specific binding. The
TransactionFlowProtocol binding property enables you to choose among two different
transaction protocols that you can use to flow a transaction. The following sections briefly
describe each of them.
WS-AtomicTransaction Protocol
The WS-AtomicTransaction (WS-AT) protocol is useful for scenarios when interoperability with
third-party protocol stacks is required.
OleTransactions Protocol
The OleTransactions protocol is useful for scenarios when interoperability with third-party
protocol stacks is not required, and the deployer of a service knows in advance that the WS-AT
protocol service is disabled locally or the existing network topology does not favor the usage of
WS-AT.
The following table shows the different types of transaction flows that can be generated using
these various combinations.
TransactionFlow
binding
TransactionFlow
binding property
TransactionFlowProtocol
binding protocol
Type of transaction
flow
Mandatory true WS-AT
Transaction must be
flowed in the
interoperable WS-AT
format.
Mandatory true OleTransactions
Transaction must be
flowed in the WCF
OleTransactions
format.
Resource Links for 70-513 WCF Certification Exam
364
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Mandatory false Not applicable
Not applicable because
this is an invalid
configuration.
Allowed true WS-AT
Transaction may be
flowed in the
interoperable WS-AT
format.
Allowed true OleTransactions
Transaction may be
flowed in the WCF
OleTransactions
format.
Allowed false Any value
A transaction is not
flowed.
NotAllowed Any value Any value
A transaction is not
flowed.
The following table summarizes the message processing result.
Incoming message
TransactionFlow
setting
Transaction header
Message processing
result
Transaction matches
expected protocol format
Allowed or
Mandatory
MustUnderstand
equals true.
Process
Transaction does not
match expected protocol
format
Mandatory
MustUnderstand
equals false.
Rejected because a
transaction is required
Transaction does not
match expected protocol
format
Allowed
MustUnderstand
equals false.
Rejected because the
header is not
understood
Transaction using any
protocol format
NotAllowed
MustUnderstand
equals false.
Rejected because the
header is not
understood
No transaction Mandatory N/A
Rejected because a
transaction is required
No transaction Allowed N/A Process
No transaction NotAllowed N/A Process
While each method on a contract can have different transaction flow requirements, the
transaction flow protocol setting is scoped at the level of the binding. This means that all
methods that share the same endpoint (and therefore the same binding) also share the same
policy allowing or requiring transaction flow, as well as the same transaction protocol if
applicable.
Enabling Transaction Flow at the Method Level
Transaction flow requirements are not always the same for all methods in a service contract.
Therefore, WCF also provides an attribute-based mechanism to allow each method's transaction
flow preferences to be expressed. This is achieved by the TransactionFlowAttribute that
Resource Links for 70-513 WCF Certification Exam
365
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
specifies the level in which a service operation accepts a transaction header. You should mark
your service contract methods with this attribute if you want to enable transaction flow. This
attribute takes one of the values of the TransactionFlowOption enumeration, in which the default
value is NotAllowed. If any value except NotAllowed is specified, the method is required to not
be one-way. A developer can use this attribute to specify method-level transaction flow
requirements or constraints at design time.
Enabling Transaction Flow at the Endpoint Level
In addition to the method-level transaction flow setting the TransactionFlowAttribute attribute
provides, WCF provides an endpoint-wide setting for transaction flow to allow administrators to
control transaction flow at a higher level. This is achieved by the
TransactionFlowBindingElement, which enables you to enable or disable incoming transaction
flow in an endpoints binding settings, as well as to specify the desired transaction protocol
format for incoming transactions.If the binding has disabled transaction flow, but one of the
operations on a service contract requires an incoming transaction, then a validation exception is
thrown at service startup. Most of the standing bindings WCF provides contain the
transactionFlow and transactionProtocol attributes to enable you to configure the specific
binding to accept incoming transactions. For more information about setting the configuration
elements, see <binding>.An administrator or deployer can use endpoint-level transaction flow to
configure transaction flow requirements or constraints at deployment time using the
configuration file.
Security
To ensure system security and integrity, you must secure message exchanges when flowing
transactions between applications. You should not flow or disclose transaction details to any
application that is not entitled to participate in the same transaction.When generating WCF
clients to unknown or untrusted Web services through the use of metadata exchange, calls to
operations on these Web services should suppress the current transaction if possible. The
following example demonstrates how to do this.
//client code which has an ambient transaction
using (TransactionScope scope = new
TransactionScope(TransactionScopeOption.Suppress))
{
// No transaction will flow to this operation
untrustedProxy.Operation1(...);
scope.Complete();
}
//remainder of client code
In addition, services should be configured to accept incoming transactions only from clients that
they have authenticated and authorized. Incoming transactions should only be accepted if they
come from highly trusted clients.
Policy Assertions
WCF uses policy assertions to control transaction flow. Policy assertions can be found in a
services policy document, which is generated by aggregating contracts, configuration, and
attributes. The client can obtain the services policy document using an HTTP GET or a WS-
MetadataExchange request-reply. Clients can then process the policy document to determine
which operations on a service contract may support or require transaction flow.Transaction flow
policy assertions affect transaction flow by specifying the SOAP headers that a client should
Resource Links for 70-513 WCF Certification Exam
366
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
send to a service to represent a transaction. All transaction headers must be marked with
MustUnderstand equal to true. Any message with a header marked otherwise is rejected with a
SOAP fault.Only one transaction-related policy assertion can be present on a single operation.
Policy documents with more than one transaction assertion on an operation are considered
invalid and are rejected by WCF. In addition, only a single transaction protocol can be present
inside each port type. Policy documents with operations referencing more than one transaction
protocol inside a single port type are considered invalid, and are rejected by the ServiceModel
Metadata Utility Tool. Policy documents with transaction assertions present on output messages
or one-way input messages are also considered invalid.
How to: Create a Transactional Service
This sample demonstrates various aspects of creating a transactional service and the use of a
client-initiated transaction to coordinate service operations.
Creating a transactional service
Create a service contract and annotate the operations with the desired setting from the
TransactionFlowOption enumeration to specify the incoming transaction requirements. Note that
you can also place the TransactionFlowAttribute on the service class being implemented. This
allows for a single implementation of an interface to use these transaction settings, instead of every
implementation.
[ServiceContract]
public interface ICalculator
{
[OperationContract]
// Use this to require an incoming transaction
[TransactionFlow(TransactionFlowOption.Mandatory)]
double Add(double n1, double n2);
[OperationContract]
// Use this to permit an incoming transaction
[TransactionFlow(TransactionFlowOption.Allowed)]
double Subtract(double n1, double n2);
}
Create an implementation class, and use the ServiceBehaviorAttribute to optionally specify a
TransactionIsolationLevel and a TransactionTimeout. You should note that in many cases, the
default TransactionTimeout of 60 seconds and the default TransactionIsolationLevel of
Unspecified are appropriate. For each operation, you can use the OperationBehaviorAttribute
attribute to specify whether work performed within the method should occur within the scope of a
transaction scope according to the value of the TransactionScopeRequired attribute. In this case, the
transaction used for the Add method is the same as the mandatory incoming transaction that is flowed
from the client, and the transaction used for the Subtract method is either the same as the incoming
transaction if one was flowed from the client, or a new implicitly and locally created transaction.
[ServiceBehavior(
TransactionIsolationLevel = System.Transactions.IsolationLevel.Serializable,
TransactionTimeout = "00:00:45")]
public class CalculatorService : ICalculator
{
[OperationBehavior(TransactionScopeRequired = true)]
public double Add(double n1, double n2)
{
// Perform transactional operation
Resource Links for 70-513 WCF Certification Exam
367
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
RecordToLog(String.Format("Adding {0} to {1}", n1, n2));
return n1 + n2;
}

[OperationBehavior(TransactionScopeRequired = true)]
public double Subtract(double n1, double n2)
{
// Perform transactional operation
RecordToLog(String.Format("Subtracting {0} from {1}", n2, n1));
return n1 - n2;
}

private static void RecordToLog(string recordText)
{
// Database operations omitted for brevity
// This is where the transaction provides specific benefit
// - changes to the database will be committed only when
// the transaction completes.
}
}
Configure the bindings in the configuration file, specifying that the transaction context should be
flowed, and the protocols to be used to do so. For more information, see ServiceModel Transaction
Configuration. Specifically, the binding type is specified in the endpoint elements binding attribute.
The <endpoint> element contains a bindingConfiguration attribute that references a binding
configuration named transactionalOleTransactionsTcpBinding, as shown in the following
sample configuration.
<service name="CalculatorService">
<endpoint
address="net.tcp://localhost:8008/CalcService"binding="netTcpBinding"bindingConf
iguration="transactionalOleTransactionsTcpBinding" contract="ICalculator"
name="OleTransactions_endpoint" />
</service>
Transaction flow is enabled at the configuration level by using the transactionFlow attribute,
and the transaction protocol is specified using the transactionProtocol attribute, as shown in the
following configuration.
<bindings>
<netTcpBinding>
<binding name="transactionalOleTransactionsTcpBinding"
transactionFlow="true"transactionProtocol="OleTransactions"/>
</netTcpBinding>
</bindings>
Supporting multiple transaction protocols
For optimal performance, you should use the OleTransactions protocol for scenarios involving a
client and service written using Windows Communication Foundation (WCF). However, the WS-
AtomicTransaction (WS-AT) protocol is useful for scenarios when interoperability with third-party
protocol stacks is required. You can configure WCF services to accept both protocols by providing
multiple endpoints with appropriate protocol-specific bindings, as shown in the following sample
configuration.
<service name="CalculatorService">
<endpoint address="http://localhost:8000/CalcService" binding="wsHttpBinding"
bindingConfiguration="transactionalWsatHttpBinding" contract="ICalculator"
name="WSAtomicTransaction_endpoint" />
Resource Links for 70-513 WCF Certification Exam
368
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<endpoint address="net.tcp://localhost:8008/CalcService"
binding="netTcpBinding"
bindingConfiguration="transactionalOleTransactionsTcpBinding"
contract="ICalculator" name="OleTransactions_endpoint" />
</service>
The transaction protocol is specified using the transactionProtocol attribute. However, this
attribute is absent from the system-provided wsHttpBinding, because this binding can only use
the WS-AT protocol.
<bindings>
<wsHttpBinding>
<binding name="transactionalWsatHttpBinding" transactionFlow="true" />
</wsHttpBinding>
<netTcpBinding>
<binding name="transactionalOleTransactionsTcpBinding"
transactionFlow="true" transactionProtocol="OleTransactions"/>
</netTcpBinding>
</bindings>
Controlling the completion of a transaction
By default, WCF operations automatically complete transactions if no unhandled exceptions are
thrown. You can modify this behavior by using the TransactionAutoComplete property and the
SetTransactionComplete method. When an operation is required to occur within the same transaction
as another operation (for example, a debit and credit operation), you can disable the autocomplete
behavior by setting the TransactionAutoComplete property to false as shown in the following
Debit operation example. The transaction the Debit operation uses is not completed until a method
with the TransactionAutoComplete property set to true is called, as shown in the operation
Credit1, or when the SetTransactionComplete method is called to explicitly mark the transaction
as complete, as shown in the operation Credit2. Note that the two credit operations are shown for
illustration purposes, and that a single credit operation would be more typical.
[ServiceBehavior]
public class CalculatorService : IAccount
{
[OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=false)]
public void Debit(double n)
{
// Perform debit operation
return;
}
[OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)]
public void Credit1(double n)
{
// Perform credit operation
return;
}
[OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=false)]
public void Credit2(double n)
{
// Perform alternate credit operation
OperationContext.Current.SetTransactionComplete();
return;
}
}
Resource Links for 70-513 WCF Certification Exam
369
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
For the purposes of transaction correlation, setting the TransactionAutoComplete property to false
requires the use of a sessionful binding. This requirement is specified with the SessionMode
property on the ServiceContractAttribute.
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IAccount
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void Debit(double n);
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void Credit1(double n);
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void Credit2(double n);
}
Controlling the lifetime of a transactional service instance
WCF uses the ReleaseServiceInstanceOnTransactionComplete property to specify whether the
underlying service instance is released when a transaction completes. Since this defaults to true,
unless configured otherwise, WCF exhibits an efficient and predictable "just-in-time" activation
behavior. Calls to a service on a subsequent transaction are assured a new service instance with no
remnants of the previous transaction's state. While this is often useful, sometimes you may want to
maintain state within the service instance beyond the transaction completion. Examples of this would
be when required state or handles to resources are expensive to retrieve or reconstitute. You can do
this by setting the ReleaseServiceInstanceOnTransactionComplete property to false. With that
setting, the instance and any associated state will be available on subsequent calls. When using this,
give careful consideration to when and how state and transactions will be cleared and completed.
The following sample demonstrates how to do this by maintaining the instance with the
runningTotal variable.
[ServiceBehavior(TransactionIsolationLevel = [ServiceBehavior(
ReleaseServiceInstanceOnTransactionComplete = false)]
public class CalculatorService : ICalculator
{
double runningTotal = 0;
[OperationBehavior(TransactionScopeRequired = true)]
public double Add(double n)
{
// Perform transactional operation
RecordToLog(String.Format("Adding {0} to {1}", n, runningTotal));
runningTotal = runningTotal + n;
return runningTotal;
}
[OperationBehavior(TransactionScopeRequired = true)]
public double Subtract(double n)
{
// Perform transactional operation
RecordToLog(String.Format("Subtracting {0} from {1}", n, runningTotal));
runningTotal = runningTotal - n;
return runningTotal;
}
private static void RecordToLog(string recordText)
{
Resource Links for 70-513 WCF Certification Exam
370
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
// Database operations omitted for brevity
}
}
Note:
Since the instance lifetime is a behavior that is internal to the service, and controlled through the
ServiceBehaviorAttribute property, no modification to the service configuration or service
contract is required to set the instance behavior. In addition, the wire will contain no representation
of this.
Diagnosing Transactional Applications
This topic describes how to use the Windows Communication Foundation (WCF) management
and diagnostics feature to troubleshoot a transactional application.
Performance Counters
WCF provides a standard set of performance counters for you to measure your transactional
application's performance. For more information, see WCF Performance Counters.
Performance counters are scoped to three different levels: service, endpoint, and operation, as
described in the following tables.
Service Performance Counters
Performance
counter
Description
Transactions Flowed
The number of transactions that flowed to operations in this service. This
counter is incremented any time a transaction is present in the message
that is sent to the service.
Transactions Flowed
Per Second
The number of transactions that flowed to operations in this service within
each second. This counter is incremented any time a transaction is present
in the message that is sent to the service.
Transacted
Operations
Committed
The number of transacted operations performed, whose transaction has
completed with the outcome committed in this service. Work done under
such operations is fully committed. Resources are updated in accordance
with the work done in the operation.
Transacted
Operations
Committed Per
Second
The number of transacted operations performed, whose transaction has
completed with the outcome committed in this service within each second.
Work done under such operations is fully committed. Resources are
updated in accordance with the work done in the operation.
Transacted
Operations Aborted
The number of transacted operations performed, whose transaction has
completed with the outcome aborted in this service. Work done under such
operations is rolled back. Resources are reverted to their previous state.
Transacted
Operations Aborted
Per Second
The number of transacted operations performed, whose transaction has
completed with the outcome aborted in this service within each second.
Work done under such operations is rolled back. Resources are reverted to
their previous state.
Transacted
Operations In Doubt
The number of transacted operations performed, whose transaction has
completed with an outcome in doubt in this service. Work done with an
Resource Links for 70-513 WCF Certification Exam
371
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
outcome in doubt is in an indeterminate state. Resources are held pending
outcome.
Transacted
Operations In Doubt
Per Second
The number of transacted operations performed, whose transaction has
completed with an outcome in doubt in this service within each second.
Work done with an outcome in doubt is in an indeterminate state.
Resources are held pending outcome.
Endpoint Performance Counters
Performance
counter
Description
Transactions
Flowed
The number of transactions that flowed to operations at this endpoint. This
counter is incremented any time a transaction is present in the message that
is sent to the endpoint.
Transactions
Flowed Per Second
The number of transactions that flowed to operations at this endpoint within
each second. This counter is incremented any time a transaction is present
in the message that is sent to the endpoint.
Operation Performance Counters
Performance
counter
Description
Transactions
Flowed
The number of transactions that flowed to operations at this endpoint. This
counter is incremented any time a transaction is present in the message that
is sent to the endpoint.
Transactions
Flowed Per Second
The number of transactions that flowed to operations at this endpoint within
each second. This counter is incremented any time a transaction is present
in the message that is sent to the endpoint.
Windows Management Instrumentation
WCF exposes inspection data of a service at run time through a WCF Windows Management
Instrumentation (WMI) provider. For more information about accessing WMI data, see Using
Windows Management Instrumentation for Diagnostics.
A number of read-only WMI properties indicate the applied transaction settings for a service.
The following tables list all of these settings.
On a service, the ServiceBehaviorAttribute has the following properties.
Name Type Description
ReleaseServiceInstanceOnTransactionComplete Boolean
Specifies whether the
service object is
recycled when the
current transaction
completes.
TransactionAutoCompleteOnSessionClose Boolean
Specifies whether
pending transactions are
completed when the
current session closes.
Resource Links for 70-513 WCF Certification Exam
372
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
TransactionIsolationLevel
A string that contains a
valid value of the
IsolationLevel
enumeration.
Specifies the transaction
isolation level that this
service supports.
TransactionTimeout DateTime
Specifies the period
within which a
transaction must
complete.
The ServiceTimeoutsBehavior has the following property.
Name Type Description
TransactionTimeout DateTime Specifies the period within which a transaction must complete.
On a binding, the TransactionFlowBindingElement has the following properties.
Name Type Description
TransactionProtocol
A string that contains a valid value of
the TransactionProtocol type.
Specifies the transaction protocol
to use in flowing a transaction.
TransactionFlow Boolean
Specifies whether incoming
transaction flow is enabled.
On an operation, the OperationBehaviorAttribute has the following properties:
Name Type Description
TransactionAutoComplete Boolean
Specifies whether to automatically commit the current
transaction if no unhandled exceptions occur.
TransactionScopeRequired Boolean Specifies whether the operation requires a transaction.
On an operation, the TransactionFlowAttribute has the following properties.
Name Type Description
TransactionFlowOption
A string that contains a valid value of the
TransactionFlowOption enumeration.
Specifies the extent to
which transaction flow is
required.
Tracing
Traces enable you to monitor and analyze faults in your transactional applications. You can
enable tracing using the following ways:
Standard WCF tracingThis type of tracing is the same as tracing any WCF application. For more
information, see Configuring Tracing.
WS-AtomicTransaction tracingWS-AtomicTransaction tracing can be enabled by using the WS-
AtomicTransaction Configuration Utility. Such tracing provides insight into the state of
transactions and participants within a system. To also enable internal Service Model tracing, you
can set the HKLM\SOFTWARE\Microsoft\WSAT\3.0\ServiceModelDiagnosticTracing
registry key to a valid value of the SourceLevels enumeration. You can enable message logging
in the same way as other WCF applications.
System.Transactions tracingWhen using the OleTransactions protocol, protocol messages
cannot be traced. The tracing support the System.Transactions infrastructure provides (which
uses OleTransactions) allows users to view events that occurred to the transactions. To enable
Resource Links for 70-513 WCF Certification Exam
373
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
tracing for a System.Transactions application, include the following code in the App.config
configuration file.
<configuration>
<system.diagnostics>
<sources>
<source name="System.Transactions" switchValue="Verbose, ActivityTracing">
<listeners>
<add name="Text"type="System.Diagnostics.XmlWriterTraceListener"
initializeData="SysTx.log" traceOutputOptions="Callstack" />
</listeners>
</source>
</sources>
<trace autoflush="true" indentsize="4">
</trace>
</system.diagnostics>
</configuration>
This also enables WCF tracing, as WCF also utilizes the System.Transactions
infrastructure.
Comparing Transactions in COM+ and
ServiceModel
This topic discusses how to simulate the behavior of a transactional COM+ service using the
Windows Communication Foundation (WCF) attributes the System.ServiceModel namespace
provides.
Emulating COM+ Using ServiceModel Attributes
The following table compares the TransactionOption enumeration used to create an
EnterpriseServices transaction and how they correlate to the WCF attributes the
System.ServiceModel namespace provides.
COM+
attribute
WCF attributes
RequiresNew
TransactionFlowAttribute is set to NotAllowed.
TransactionScopeRequired is true.
The TransactionFlow attribute in the binding element is false.
Required
TransactionFlowAttribute is set to Allowed.
TransactionScopeRequired is true.
The TransactionFlow attribute in the binding element is true.
Supported
There is no direct equivalent. In general, you should adopt the behavior specified
for Required instead.
NotSupported
TransactionScopeRequired is false.
The TransactionFlow attribute in the binding element is false.
Disabled
There is no direct equivalent. In general, you should adopt the behavior specified
for NotSupported instead.
Resource Links for 70-513 WCF Certification Exam
374
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Integrating Enterprise Services Transactional
Components
Windows Communication Foundation (WCF) provides an automatic mechanism for integrating
with Enterprise Services (see Integrating with COM+ Applications). However, you may want the
flexibility to develop services that internally use transactional components hosted within
Enterprise Services. Because the WCF Transactions feature is built on the System.Transactions
infrastructure, the process for integrating Enterprise Services with WCF is identical to that for
specifying interoperability between System.Transactions and Enterprise Services, as outlined in
Interoperability with Enterprise Services and COM+ Transactions.
To provide the desired level of interoperability between the incoming flowed transaction and the
COM+ context transaction, the service implementation must create a TransactionScope instance
and use the appropriate value from the EnterpriseServicesInteropOption enumeration.
Integrating Enterprise Services with a Service Operation
The following code demonstrates an operation, with Allowed transaction flow, that creates a
TransactionScope with the Full option. The following conditions apply in this scenario:
If the client flows a transaction, the operation, including the call to the Enterprise Services
component, is executed within the scope of that transaction. Using Full ensures that the
transaction is synchronized with the System.EnterpriseServices context, which means that the
ambient transaction for System.Transactions and the System.EnterpriseServices is the same.
If the client does not flow a transaction, setting TransactionScopeRequired to true creates a new
transaction scope for the operation. Similarly, using Full ensures that the operations transaction
is the same as the transaction used inside the System.EnterpriseServices component's context.
Any additional method calls also occur within the scope of the same operations transaction.
[ServiceContract()]
public interface ICustomerServiceContract
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Allowed)]
void UpdateCustomerNameOperation(int customerID, string newCustomerName);
}
[ServiceBehavior(TransactionIsolationLevel =
System.Transactions.IsolationLevel.Serializable)]
public class CustomerService : ICustomerServiceContract
{
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public void UpdateCustomerNameOperation(int customerID, string
newCustomerName)
{
// Create a transaction scope with full ES interop
using (TransactionScope ts = new TransactionScope(
TransactionScopeOption.Required,
new TransactionOptions(),
EnterpriseServicesInteropOption.Full))
{
// Create an Enterprise Services component
// Call UpdateCustomer method on an Enterprise Services
// component
Resource Links for 70-513 WCF Certification Exam
375
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
// Call UpdateOtherCustomerData method on an Enterprise
// Services component
ts.Complete();
}
// Do UpdateAdditionalData on an non-Enterprise Services
// component
}
}
If no synchronization is required between an operations current transaction and calls to
transactional Enterprise Services components, then use the None option when instantiating the
TransactionScope instance.
Integrating Enterprise Services with a Client
The following code demonstrates client code using a TransactionScope instance with the Full
setting. In this scenario, calls to service operations that support transaction flow occur within the
scope of the same transaction as the calls to Enterprise Services components.
static void Main()
{
// Create a client
CalculatorClient client = new CalculatorClient();
// Create a transaction scope with full ES interop
using (TransactionScope ts = new
TransactionScope(TransactionScopeOption.Required,new TransactionOptions(),
EnterpriseServicesInteropOption.Full))
{
// Call Add calculator service operation
// Create an Enterprise Services component
// Call UpdateCustomer method on an Enterprise Services
// component
ts.Complete();
}
// Closing the client gracefully closes the connection and
// cleans up resources
client.Close();
}
Manage concurrency.This objective may include but is not limited to: single, multiple, and
reentrant concurrency modes; SynchronizationContext and CallbackBehaviorThis objective does
not include: deadlocks and other multithreading issues One of the more useful features of the
Windows Communication Foundation (WCF) is its reliance on the Microsoft .NET
Framework synchronization context to marshal calls to the service instance (or to a callback
object). This mechanism provides for both productivity-oriented development and for powerful
extensibility. In this column, I describe briefly what synchronization contexts are and how WCF
uses them, and then proceed to demonstrate various options for extending WCF to use custom
synchronization contexts, both programmatically and declaratively. In addition to seeing the
merits of custom synchronization contexts, you will also see some advanced .NET programming
as well as WCF extensibility techniques.
What Are .NET Synchronization Contexts?
The .NET Framework 2.0 introduced a little-known feature called the synchronization context,
defined by the class SynchronizationContext in the System.Threading namespace:
public delegate void SendOrPostCallback(object state); public class
SynchronizationContext { public virtual void Post(SendOrPostCallback
Resource Links for 70-513 WCF Certification Exam
376
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
callback,object state); public virtual void Send(SendOrPostCallback
callback,object state); public static void SetSynchronizationContext
(SynchronizationContext context); public static SynchronizationContext
Current {get;} //More members }
The synchronization context is stored in the thread local storage (TLS). Every thread created
with the .NET Framework 2.0 may have a synchronization context (similar to an ambient
transaction) obtained via the static Current property of SynchronizationContext. Current may
return null if the current thread has no synchronization context. The synchronization context is
used to bounce a method call between a calling thread and a target thread or threads, in case the
method cannot execute on the original calling thread. The calling thread wraps the method it
wants to marshal to the other thread (or threads) with a delegate of the type SendOrPostCallback,
and provides it to the Send or Post methods, for synchronous or asynchronous execution
respectively. You can associate a synchronization context with your current thread by calling the
static method SetSynchronizationContext.By far, the most common use of a synchronization
context is with UI updates. With all multithreaded Windows technologies, from MFC to
Windows Forms to WPF, only the thread that created a window is allowed to update it by
processing its messages. This constraint has to do with the underlying use of the Windows
message loop and the thread messaging architecture. The messaging architecture creates a
problem when developing a multithreaded UI applicationyou would like to avoid blocking the
UI when executing lengthy operations or receiving callbacks. This, of course, necessitates the
use of worker threads, yet those threads cannot update the UI directly because they are not the UI
thread.In order to address this problem in the .NET Framework 2.0, the constructor of any
Windows Forms-based control or form checks to see if the thread it is running on has a
synchronization context, and if it does not have one, the constructor attaches a new
synchronization context (called WindowsFormsSynchronizationContext). This dedicated
synchronization context converts all calls to its Post or Send methods into Windows messages
and posts them to the UI thread message queue to be processed on the correct thread. The
Windows Forms synchronization context is the underlying technology behind the commonly
used BackgroundWorker helper control.
WCF and Synchronization Contexts
By default, all WCF service calls (and callbacks) execute on threads from the I/O Completion
thread pool. That pool has 1,000 threads by default, none of them under the control of your
application. Now imagine a service that needs to update some user interface. The service should
not access the form, control or window directly because it is on the wrong thread. To deal with
that, the ServiceBehaviorAttribute offers the UseSynchronizationContext property, defined as:
[AttributeUsage(AttributeTargets.Class)] public sealed class
ServiceBehaviorAttribute : ... { public bool UseSynchronizationContext
{get;set;} //More members }
The default value of UseSynchronizationContext is set to true. To determine which
synchronization context the service should use, WCF looks at the thread that opened the host. If
that thread has a synchronization context and UseSynchronizationContext is set to true, then
WCF automatically marshals all calls to the service to that synchronization context. There is no
explicit interaction with the synchronization context required of the developer. WCF does that by
providing the dispatcher of each endpoint with a reference to the synchronization context, and
the dispatcher uses that synchronization context to dispatch all calls.For example, suppose the
service MyService (defined in Figure 1) needs to update some UI on the form MyForm. Because
Resource Links for 70-513 WCF Certification Exam
377
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
the host is opened after the form is constructed, the opening thread already has a synchronization
context, and so all calls to the service will automatically be marshaled to the correct UI thread.
Figure 1 Using the UI Synchronization Context
[ServiceContract] interface IMyContract {...} class MyService : IMyContract {
/* some code to update MyForm */ } class MyForm : Form {...} static class
Program { static void Main() { Form form = new MyForm();//Sync context
established here ServiceHost host = new ServiceHost(typeof(MyService));
host.Open(); Application.Run(form); host.Close(); } }
If you were to simply open the host in Main and use the code generated by the Windows Forms
designer, you would not benefit from the synchronization context, since the host is opened
without it present:
//No automatic use of synchronization context static void Main() {
ServiceHost host = new ServiceHost(typeof(MyService)); host.Open();
Application.Run(new MyForm());//Synchronization context //established here
host.Close(); }
Service Custom Synchronization Context
Utilizing a custom synchronization context by your service or resources has two aspects to it:
implementing the synchronization context and then installing it. The source code accompanying
this column contains my ThreadPoolSynchronizer class, which is defined as:
public class ThreadPoolSynchronizer : SynchronizationContext,IDisposable {
public ThreadPoolSynchronizer(uint poolSize); public
ThreadPoolSynchronizer(uint poolSize,string poolName); public void Dispose();
public void Close(); public void Abort(); }
ThreadPoolSynchronizer marshals all calls to a custom thread pool, where the calls are first
queued up, then multiplexed on the available threads. The size of the pool is provided as a
construction parameter. If the pool is maxed out, the call will be pending in the queue until a
thread is available. You can also provide a pool name (which will be the prefix of the name of
the threads in the pool). Disposing or closing ThreadPoolSynchronizer kills all threads in the
pool gracefully, that is, after allowing the engaged threads to complete their task. The Abort
method causes a less-than-graceful shutdown, as it terminates all threads abruptly. Implementing
ThreadPoolSynchronizer had nothing to do with WCF, so I chose not to include the code in this
column. The classic use for a custom thread pool is with a server application that needs to
maximize its throughput by controlling the underlying worker threads and their assignments.
To associate your service with the custom thread pool, you can manually attach
ThreadPoolSynchronizer to the thread opening the host:
SynchronizationContext syncContext = new ThreadPoolSynchronizer(3);
SynchronizationContext.SetSynchronizationContext(syncContext);
using(syncContext as IDisposable) { ServiceHost host = new
ServiceHost(typeof(MyService)); host.Open(); /* Some blocking operations */
host.Close(); }
The thread pool will have three threads. Using the same service definition as in Figure 1,
MyService will have an affinity to those threads. All calls to the service will be channeled to
them, regardless of the service concurrency mode or instancing mode, and across all endpoints
and contracts supported by the service.
The problem with the above code is that the service is at the mercy of the hosting code. What if,
by design, the service is required to execute on the pool? It would be better to apply the thread
pool declaratively, as part of the service definition. To that end, I wrote the
ThreadPoolBehaviorAttribute:
Resource Links for 70-513 WCF Certification Exam
378
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
[AttributeUsage(AttributeTargets.Class)] public class
ThreadPoolBehaviorAttribute : Attribute, IContractBehavior, IServiceBehavior
{ public ThreadPoolBehaviorAttribute(uint poolSize,Type serviceType); public
ThreadPoolBehaviorAttribute(uint poolSize,Type serviceType, string poolName);
}
You apply the attribute directly on the service, while providing the service type as a constructor
parameter:
[ThreadPoolBehavior(3,typeof(MyService))] class MyService : IMyContract {...}
The attribute provides an instance of ThreadPoolSynchronizer to the dispatchers of the service's
endpoints. The key in implementing ThreadPoolBehaviorAttribute is knowing how and when to
hook up the dispatchers with the synchronization context. To facilitate this,
ThreadPoolBehaviorAttribute supports the special WCF extensibility interface
IContractBehavior:
public interface IContractBehavior { void
ApplyDispatchBehavior(ContractDescription description, ServiceEndpoint
endpoint, DispatchRuntime dispatch); // More members }
When a service is decorated with an attribute that supports IContractBehavior, after opening the
host (but before forwarding calls to the service) and for each service endpoint, WCF calls the
ApplyDispatchBehavior method, providing it with the DispatchRuntime parameter allowing it to
affect the dispatcher. Figure 2 lists the implementation of ThreadPoolBehaviorAttribute.
Figure 2 Implementing ThreadPoolBehaviorAttribute
[AttributeUsage(AttributeTargets.Class)] public class
ThreadPoolBehaviorAttribute : Attribute,IContractBehavior, IServiceBehavior {
//Store values in matching members protected string PoolName
{get{...};set{...};} protected uint PoolSize {get{...};set{...};} protected
Type ServiceType {get{...};set{...};} public ThreadPoolBehaviorAttribute(uint
poolSize,Type serviceType) : this(poolSize,serviceType,null) {} public
ThreadPoolBehaviorAttribute(uint poolSize,Type serviceType, string poolName)
{ PoolName = poolName; ServiceType = serviceType; PoolSize = poolSize; }
protected virtual ThreadPoolSynchronizer ProvideSynchronizer() {
if(ThreadPoolHelper.HasSynchronizer(ServiceType) == false) return new
ThreadPoolSynchronizer(PoolSize,PoolName); else return
ThreadPoolHelper.GetSynchronizer(ServiceType); } void
IContractBehavior.ApplyDispatchBehavior (ContractDescription
description,ServiceEndpoint endpoint, DispatchRuntime dispatch) { PoolName =
PoolName ?? "Pool executing endpoints of " + ServiceType;
ThreadPoolHelper.ApplyDispatchBehavior(ProvideSynchronizer(),
PoolSize,ServiceType,PoolName,dispatchRuntime); } void
IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase
serviceHostBase) { serviceHostBase.Closed += delegate {
ThreadPoolHelper.CloseThreads(ServiceType); }; } //Rest of the implementation
} public static class ThreadPoolHelper { static
Dictionary<Type,ThreadPoolSynchronizer> m_Synchronizers = new
Dictionary<Type,ThreadPoolSynchronizer>();
[MethodImpl(MethodImplOptions.Synchronized)] internal static bool
HasSynchronizer(Type type) { return m_Synchronizers.ContainsKey(type); }
[MethodImpl(MethodImplOptions.Synchronized)] internal static
ThreadPoolSynchronizer GetSynchronizer(Type type) { return
m_Synchronizers[type]; } [MethodImpl(MethodImplOptions.Synchronized)]
internal static void ApplyDispatchBehavior( ThreadPoolSynchronizer
synchronizer,uint poolSize,Type type, string poolName,DispatchRuntime
dispatch) { if(HasSynchronizer(type) == false) { m_Synchronizers[type] =
synchronizer; } dispatch.SynchronizationContext = m_Synchronizers[type]; }
Resource Links for 70-513 WCF Certification Exam
379
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
[MethodImpl(MethodImplOptions.Synchronized)] public static void
CloseThreads(Type type) { if(m_Synchronizers.ContainsKey(type)) {
m_Synchronizers[type].Dispose(); m_Synchronizers.Remove(type); } } }
It is a best practice to separate the implementation of a WCF custom behavior attribute from the
actual behavior. Let the attribute merely decide on the sequence of events and have a helper class
provide the actual behavior. Doing so lets you use the behavior separately, for instance by a
custom host. This is why ThreadPoolBehaviorAttribute does not do muchit delegates most of
its work to a static helper class called ThreadPoolHelper. The ThreadPoolHelper class provides
the HasSynchronizer method, which tells if the specified service type already has a
synchronization context, and the GetSynchronizer method, which returns the synchronization
context associated with the type. ThreadPoolBehaviorAttribute uses these two methods in the
virtual ProvideSynchronizer method to ensure that it creates the pool exactly once for the service
type. This check is required since ApplyDispatchBehavior can be called multiple times once
per endpoint, in fact. ThreadPoolBehaviorAttribute is also a custom service behavior because it
implements IServiceBehavior:
public interface IServiceBehavior { void Validate(ServiceDescription
description,ServiceHostBase host); //More members }
The Validate method of IServiceBehavior uses the service host instance to subscribe to the host
Closed event, where it asks ThreadPoolHelper to terminate all the threads in the pool.
What ThreadPoolHelper does is associate all dispatchers of all endpoints of that service type
with the same instance of ThreadPoolSynchronizer. This ensures that all calls are routed to the
same pool. ThreadPoolHelper has to be able to map a service type to a particular
ThreadPoolSynchronizer, so it declares a static dictionary called m_Synchronizers that uses
service types as keys, and ThreadPoolSynchronizer instances as values.
In ApplyDispatchBehavior, ThreadPoolHelper checks to see if m_Synchronizers already
contains the provided service type. If the type is not found, ThreadPoolHelper adds the provided
ThreadPoolSynchronizer to m_Synchronizers, associating it with the service type. After that, it
simply assigns the ThreadPoolSynchronizer instance to the dispatcher:
dispatch.SynchronizationContext = m_Synchronizers[type];
This single line is all that is required to have WCF use the custom synchronization context from
now on. In the CloseThreads method, ThreadPoolHelper looks up from the dictionary the
ThreadPoolSynchronizer instance and disposes of it (thus gracefully terminating all the worker
threads in the pool). All access to the dictionary is automatically synchronized via the
MethodImpl attribute and the MethodImplOptions.Synchronized flag. ThreadPoolHelper also
verifies that the provided pool size value does not exceed the max concurrent calls value of the
dispatcher throttle (not shown in Figure 2).
Thread Affinity Synchronization ContextA pool size of one will in effect create an affinity
between a particular thread and all service calls, regardless of the service concurrency and
instancing modes. This is particularly useful if the service is required to create some UI, such as
a pop-up window, and periodically show, hide, and update it. Being the party creating the
window, the service must enforce the fact it is being called on the same thread. Another use for
thread affinity is a service that accesses or creates resources that use the TLS. To formalize such
requirements, I create the specialized AffinitySynchronizer like so:
public class AffinitySynchronizer : ThreadPoolSynchronizer { public
AffinitySynchronizer() : this("AffinitySynchronizer Worker Thread") {} public
AffinitySynchronizer(string threadName): base(1,threadName) {} }
Resource Links for 70-513 WCF Certification Exam
380
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
While you can install AffinitySynchronizer as in the earlier referenced code, I also defined the
ThreadAffinityBehaviorAttribute in Figure 3. This attribute can be used like this:
Figure 3 ThreadAffinityBehaviorAttribute
[AttributeUsage(AttributeTargets.Class)] public class
ThreadAffinityBehaviorAttribute : ThreadPoolBehaviorAttribute { public
ThreadAffinityBehaviorAttribute(Type serviceType) :
this(serviceType,"Affinity Worker Thread") {} public
ThreadAffinityBehaviorAttribute( Type serviceType,string
threadName):base(1,serviceType, threadName) {} }
[ThreadAffinityBehavior(typeof(MyService))] class MyService : IMyContract
{...}
When relying on thread affinity, all service instances are always thread safe, since only a single
thread (and the same thread at that) can access them. Configuring the service with
ConcurrencyMode .Multiple amounts to creating single-threaded access. Also, be aware that
configuring with ConcurrencyMode.Reentrant does not actually provide for reentrancy, since no
reentrancy is possible while the single thread is blocked on the call out. It is best to select the
default value of ConcurrencyMode.Single when relying on thread affinity.Priority Processing
By default, all calls to your WCF service will be processed in the order in which they arrive. This
is true both if you use the I/O Completion Ports thread pool or the custom thread pool. Normally,
this is exactly what you want. But what if some calls have higher priority and you want to
process them as soon as they arrive, rather then handling them in order? Even worse, what if the
load on your service is such that the underlying service resources are exhausted? What if the
throttle is maxed out? In these cases, your higher priority calls will be queued just as the other
calls, waiting for the service or its resources to become available. Synchronization contexts offer
an elegant solution to this problem: assign a priority to the calls, and have the synchronization
context sort the calls as they arrive, before dispatching them to the thread pool for execution.
This is exactly what my PrioritySynchronizer class (defined in Figure 4) does.
Figure 4 PrioritySynchronizer
public enum CallPriority { Low, Normal, High } public class
PrioritySynchronizer : ThreadPoolSynchronizer { public
PrioritySynchronizer(uint poolSize); public PrioritySynchronizer(uint
poolSize,string poolName); public static CallPriority Priority {get;set;} }
PrioritySynchronizer derives from ThreadPoolSynchronizer and adds the sorting I just
mentioned. Since the Send and Post methods of SynchronizationContext do not take a priority
parameter, the client of PrioritySynchronizer has two ways of passing the priority of the call: the
first is via the Priority property, which stores the priority (a value of the enum type CallPriority)
in the TLS of the calling thread. The second option is via the message headers, which I will
discuss later in this column. If left unspecified, Priority defaults to CallPriority.Normal.
I also provide the matching PriorityCallsBehaviorAttribute shown in Figure 5. Using
PriorityCallsBehaviorAttribute is straightforward, as you can see here:
Figure 5 Implementing PriorityCallsBehaviorAttribute
[AttributeUsage(AttributeTargets.Class)] public class
PriorityCallsBehaviorAttribute : ThreadPoolBehaviorAttribute { public
PriorityCallsBehaviorAttribute(uint poolSize,Type serviceType) :
this(poolSize,serviceType,null) {} public PriorityCallsBehaviorAttribute(uint
poolSize,Type serviceType, string poolName) :
base(poolSize,serviceType,poolName) {} protected override
ThreadPoolSynchronizer ProvideSynchronizer() {
if(ThreadPoolHelper.HasSynchronizer(ServiceType) == false) return new
Resource Links for 70-513 WCF Certification Exam
381
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
PrioritySynchronizer(PoolSize,PoolName); else return
ThreadPoolHelper.GetSynchronizer(ServiceType); } }
[PriorityCallsBehavior(3,typeof(MyService))] class MyService : IMyContract
{...}
PriorityCallsBehaviorAttribute overrides ProvideSynchronizer and provides
PrioritySynchronizer instead of ThreadPoolSynchronizer. Because PrioritySynchronizer derives
from ThreadPoolSynchronizer, this is transparent as far as ThreadPoolHelper is concerned
The real challenge in implementing and supporting priority processing is providing the call
priority from the client to the service, and ultimately to PrioritySynchronizer. Using the Priority
property of PrioritySynchronizer is only useful for non-WCF clients that interact directly with
the synchronization context; it is of no use for a WCF client, whose thread is never used to
access the service. While you could provide the priority as an explicit parameter in every
method, I wanted a generic mechanism that could be applied on any contract and service. To that
end, you have to pass the priority of the call out-of-band, via the message headers. In my
February 2007 Foundations column called "Build a Queued WCF Response Service" (see
msdn.microsoft.com/msdnmag/issues/07/02/Foundations), I faced a similar problempassing
the address of the response service out-of-band to the serviceand I explain in detail the use of
the incoming and outgoing headers. While I could use exactly the same technique here, it would
be repetitive work. It is better to therefore extend the technique shown in that column, and
augment WCF with general-purpose management of extraneous information from the client to
the service, in effect, a generic yet type-safe and application-specific custom context. This is
what the GenericContext<T> class provides. Figure 6 shows its implementation with error
handling removed.
Figure 6 GenericContext Class
[DataContract] public class GenericContext<T> { [DataMember] public readonly
T Value; public GenericContext(T value) { Value = value; } public
GenericContext() : this(default(T)) {} public static GenericContext<T>
Current { get { OperationContext context = OperationContext.Current;
if(context == null) return null; return
context.IncomingMessageHeaders.GetHeader<GenericContext<T>>
typeof(T).ToString(), typeof(T).Namespace); } set { OperationContext context
= OperationContext.Current; MessageHeader<GenericContext<T>> genericHeader =
new MessageHeader<GenericContext<T>>(value);
context.OutgoingMessageHeaders.Add(genericHeader.GetUntypedHeader(
typeof(T).ToString(), typeof(T).Namespace)); } } }
GenericContext<T> completely encapsulates the interaction with the message headers. All a
client has to do to pass additional information to the service is set the static Current property
inside a new OperationContextScope. For example, to pass the number 4 in the headers, use code
as shown in Figure 7. You can further encapsulate GenericContext<T> via type-specific
derivation such as IntContext shown in Figure 8.
Figure 8 Integer Context
[DataContract] public class IntContext : GenericContext<int> { public
IntContext() {} public IntContext(int number) : base(number) {} public static
int Number { get return Current.Value; set Current = new IntContext(value); }
}
Figure 7 Using GenericContext
MyContractClient proxy = new MyContractClient(); using(OperationContextScope
contextScope = new OperationContextScope(proxy.InnerChannel)) {
GenericContext<int>.Current = new GenericContext<int>(4); proxy.MyMethod(); }
Using IntContext, Figure 7 would contain a line such as:
Resource Links for 70-513 WCF Certification Exam
382
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
IntContext.Current = 4;
Literally any data contract (or serializable) type can be used for the type parameter in the custom
context. On the service side, to read the value out of the custom headers, any downstream party
can write:
int number = GenericContext<int>.Current.Value;
or using the type-specific custom context:
int number = IntContext.Number;
This is exactly what PrioritySynchronizer does when looking for the call priority. It expects the
clients to provide the priority either in the TLS (via the Priority property) or in the form of a
custom context that stores the priority in the message headers, using code similar to what you
saw already in Figure 7:
GenericContext<CallPriority>.Current = new
GenericContext<CallPriority>(CallPriority.High); proxy.MyMethod();
However, I was not quite happy with such code because it is exposed, it couples the client to the
priority mechanism, and it forces the client to set the priority every time before using the proxy.
To deal with these issues, I created the HeaderClientBase<T,H> proxy base class shown in
Figure 9.
Figure 9 HeaderClientBase
public abstract partial class HeaderClientBase<T,H> : ClientBase<T> where T :
class { protected H Header; public HeaderClientBase() : this(default(H)) {}
public HeaderClientBase(string endpointName) : this(default(H),endpointName)
{} public HeaderClientBase(H header) { Header = header; } public
HeaderClientBase(H header,string endpointName) : base(endpointName) { Header
= header; } /* More constructors */ protected virtual object Invoke(string
operation,params object[] args) { using(OperationContextScope contextScope =
new OperationContextScope(InnerChannel)) { GenericContext<H>.Current = new
GenericContext<H>(Header); Type contract = typeof(T); MethodInfo methodInfo =
contract.GetMethod(operation); return methodInfo.Invoke(Channel,args); } } }
Like its base class, HeaderClientBase<T,H> accepts the contract type parameter T, but also the
custom header type H. HeaderClientBase<T,H> uses the default value of H or a construction-
time provided value to pass for all calls. Lacking a code generator support such as SvcUtil, I
resorted to reflection to invoke the actual service operation, while completely encapsulating the
interaction with the generic context and the operation context scope. You need to derive from
HeaderClientBase<T,H> and provide your desired header type, as in Figure 10, providing an
integer.
Figure 10 Using HeaderClientBase
[ServiceContract] interface IMyContract { [OperationContract] void
MyMethod(string text); } class MyContractClient :
HeaderClientBase<IMyContract,int>,IMyContract { public MyContractClient(int
number) : base(number) {} public void MyMethod(string text) {
Invoke("MyMethod",text); } }
By using the code in Figure 10, you can see that Figure 7 is reduced to merely:
MyContractClient proxy = new MyContractClient(4); proxy.MyMethod();
While you could use the same technique as shown in Figure 10 to pass the call priority, for
generality's sake it is better to define a general-purpose priority-enabled proxy, the
PriorityClientBase<T>, shown in Figure 11.
Figure 11 Defining PriorityClientBase
public abstract partial class PriorityClientBase<T> :
HeaderClientBase<T,CallPriority> where T : class { public
PriorityClientBase() : this(PrioritySynchronizer.Priority) {} public
Resource Links for 70-513 WCF Certification Exam
383
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
PriorityClientBase(string endpointName) :
this(PrioritySynchronizer.Priority,endpointName) {} public
PriorityClientBase(Binding binding, EndpointAddress remoteAddress) :
this(PrioritySynchronizer.Priority,binding,remoteAddress) {} public
PriorityClientBase(CallPriority priority) : base(priority) {} public
PriorityClientBase(CallPriority priority,string endpointName) :
base(priority,endpointName) {} public PriorityClientBase(CallPriority
priority,Binding binding, EndpointAddress remoteAddress) :
base(priority,binding,remoteAddress) {} /* More constructors */ }
PriorityClientBase<T> hardcodes the use of CallPriority for the type parameter H. Also,
PriorityClientBase<T> defaults to reading the priority from the TLS (yielding
CallPriority.Normal when not found), so it can be used like any other proxy class. With very
minor changes to your existing proxy classes, you can now add priority processing support, as
shown in Figure 12.
Figure 12 Priority Processing Support
class MyContractClient : PriorityClientBase<IMyContract>,IMyContract {
//Reads priority from TLS public MyContractClient() {} public
MyContractClient(CallPriority priority) : base(priority) {} public void
MyMethod(string text) { Invoke("MyMethod",text); } } MyContractClient proxy =
new MyContractClient(CallPriority.High); proxy.MyMethod();
Callbacks and Synchronization Context
When it comes to synchronization contexts, WCF offers similar support for callback objects with
the CallbackBehaviorAttribute applied on the callback type:
[AttributeUsage(AttributeTargets.Class)] public sealed class
CallbackBehaviorAttribute : Attribute,... { public bool
UseSynchronizationContext {get;set;} //More members }
As with the ServiceBehaviorAttribute, UseSynchronizationContext defaults to true. The
interesting aspect of a callback object is when affinity to the synchronization context is locked in.
WCF will examine the thread that opens the proxy that establishes the duplex communication. If
that thread has a synchronization context, then that context will be used for all callbacks. While
you could manually install a custom synchronization context by explicitly setting it before
opening the proxy, it is better to do so declaratively using an attribute. To affect the callback
endpoint dispatcher, the attribute needs to implement the IEndpointBehavior interface:
public interface IEndpointBehavior { void ApplyClientBehavior(ServiceEndpoint
endpoint, ClientRuntime clientRuntime); //More members }
In the ApplyClientBehavior method, the ClientRuntime parameter contains a reference to the
endpoint dispatcher with the CallbackDispatchRuntime property:
public sealed class ClientRuntime { public DispatchRuntime
CallbackDispatchRuntime {get;} //More members }
The rest is identical to the service-side attribute, as demonstrated by my
CallbackThreadPoolBehaviorAttribute in Figure 13.
Figure 13 CallbackThreadPoolBehaviorAttribute
[AttributeUsage(AttributeTargets.Class)] public class
CallbackThreadPoolBehaviorAttribute :
ThreadPoolBehaviorAttribute,IEndpointBehavior { public
CallbackThreadPoolBehaviorAttribute(uint poolSize, Type clientType) :
this(poolSize,clientType,null) {} public
CallbackThreadPoolBehaviorAttribute(uint poolSize, Type clientType,string
poolName) : base(poolSize,clientType,poolName) {
AppDomain.CurrentDomain.ProcessExit += delegate {
ThreadPoolHelper.CloseThreads(ServiceType); }; } void
Resource Links for 70-513 WCF Certification Exam
384
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
IEndpointBehavior.ApplyClientBehavior (ServiceEndpoint
serviceEndpoint,ClientRuntime clientRuntime) { IContractBehavior
contractBehavior = this;
contractBehavior.ApplyDispatchBehavior(null,serviceEndpoint,
clientRuntime.CallbackDispatchRuntime); } //Rest of the implementation }
In fact, in the callback attribute I wanted to reuse as much of the service attribute as possible. To
that end, CallbackThreadPoolBehaviorAttribute derives from ThreadPoolBehaviorAttribute. Its
constructors pass the client type to the base constructors as the service type. The
CallbackThreadPoolBehaviorAttribute implementation of ApplyClientBehavior queries its base
class for IContractBehavior (this is how a subclass uses an explicit private interface
implementation of its base class) and delegates the implementation to ApplyDispatchBehavior.
The big difference between a client callback attribute and a service attribute is that the callback
scenario has no host object to subscribe to its Closed event. To compensate,
CallbackThreadPoolBehaviorAttribute monitors the process exit event to close all the threads in
the pool. If the client wants to expedite closing those threads, the client can use
ThreadPoolBehavior.CloseThreads, as shown in Figure 14.
Figure 14 Using CallbackThreadPoolBehaviorAttribute
[ServiceContract(CallbackContract = typeof(IMyContractCallback))] interface
IMyContract { [OperationContract] void MyMethod(); } interface
IMyContractCallback { [OperationContract] void OnCallback(); }
[CallbackThreadPoolBehavior(3,typeof(MyClient))] class MyClient :
IMyContractCallback,IDisposable { MyContractClient m_Proxy; public void
CallService() { m_Proxy = new MyContractClient(new InstanceContext(this));
m_Proxy.MyMethod(); } //Called by threads from the custom pool public void
OnCallback() {...} public void Dispose() { m_Proxy.Close();
ThreadPoolHelper.CloseThreads(typeof(MyClient)); } }
Just like the service side, to have all the callbacks execute on the same thread (perhaps to create
some UI on the callback side), you can configure the callbacks to have a pool size of 1. Better
yet, you can define a dedicated callback attribute for such same-thread affinity, as in Figure 15.
Figure 15 CallbackThreadAffinityBehaviorAttribute
[AttributeUsage(AttributeTargets.Class)] public class
CallbackThreadAffinityBehaviorAttribute : CallbackThreadPoolBehaviorAttribute
{ public CallbackThreadAffinityBehaviorAttribute(Type clientType) :
this(clientType,"Callback Worker Thread") {} public
CallbackThreadAffinityBehaviorAttribute(Type clientType, string threadName) :
base(1,clientType,threadName) {} }
Why Use Synchronization Contexts?
Synchronization contexts in the .NET Framework 2.0 are a powerful construct, and coupled with
WCF, they yield a superior and productive programming model. The extensibility inherent to
WCF makes this combination especially powerful, accomplishing difficult tasks such as thread
affinity and priority processing with relatively few lines of code, and all outside the scope of
your service. The custom headers and generic context techniques I demonstrated in this column
are useful across the landscape of WCF programming. Wherever out-of-band parameters are
called for, they provide an elegant, concise and type-safe solution. I also wanted to share with
you my thought processes and the trade-offs to consider when evolving your own custom WCF
extensions.
Manage consistency between instances, sessions, transactions, and concurrency.This objective
may include but is not limited to: possible combinations between instances, sessions,
Resource Links for 70-513 WCF Certification Exam
385
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
transactions, and concurrency (for example, instance mode single with concurrency mode
multiple)
o Sessions, Instancing, and Concurrency in Windows Communication Foundation (MSDN)
Monitoring and Troubleshooting Distributed Systems (14%)
Configure message logging.This objective may include but is not limited to: configuring
message listeners; logging level; message filters; configuring logging known PIIThis objective
does not include: secure message logs
Configuring Message Logging
This topic describes how you can configure message logging for different scenarios.
Enabling Message Logging
Windows Communication Foundation (WCF) does not log messages by default. To activate
message logging, you must add a trace listener to the System.ServiceModel.MessageLogging
trace source, and set attributes for the <messagelogging> element in the configuration file.
The following is an example of enabling logging and specifying additional options.
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="messages"type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\logs\messages.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="false"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false"
maxMessagesToLog="3000" maxSizeOfMessageToLog="2000"/>
</diagnostics>
</system.serviceModel>
For more information on message logging settings, see Recommended Settings for Tracing and
Message Logging.You can use add to specify the name and type of the listener you want to use.
In our example configuration, we named the Listener "messages" and add the standard .NET
Framework trace listener (System.Diagnostics.XmlWriterTraceListener) as the type we want
to use. If you use System.Diagnostics.XmlWriterTraceListener, you must specify the output
file location and name in the configuration file. This is done by setting initializeData to the
name of the log file. Otherwise, the system throws an exception. You can also implement a
custom listener that emits logs to a default file.
Caution:
Because message logging consumes disk space, you should limit the number of messages that
are written to disk for a particular service. When the message limit is reached, a trace at the
Information level is produced and all message logging activities stop.
The logging level, as well as the additional options, are discussed in the section.
Resource Links for 70-513 WCF Certification Exam
386
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The switchValue attribute of a source is only valid for tracing. If you specify a switchValue
attribute for the System.ServiceModel.MessageLogging trace source as follows, it has no
effect.
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose">
If you want to disable the trace source, you should use the logMessagesAtServiceLevel,
logMalformedMessages, and logMessagesAtTransportLevel attributes of the
messageLogging element instead. You should set all these attributes to false. This can be done
by using the configuration file in the previous code example, through the Configuration Editor
UI interface, or using WMI. For more information on the Configuration Editor tool, see
Configuration Editor Tool (SvcConfigEditor.exe). For more information on WMI, see Using
Windows Management Instrumentation for Diagnostics.
Logging Levels and Options
For incoming messages, logging happens immediately after the message is formed, immediately
before the message gets to user code in the service level, and when malformed messages are
detected.For outgoing messages, logging happens immediately after the message leaves user
code, and immediately before the message goes on the wire. WCF logs messages at two different
levels, service and transport. Malformed messages are also logged. The three categories are
independent from each other and can be activated separately in configuration.You can control the
logging level by setting the logMessagesAtServiceLevel, logMalformedMessages, and
logMessagesAtTransportLevel attributes of the messageLogging element.
Service Level
Messages logged at this layer are about to enter (on receiving) or leave (on sending) user code. If
filters have been defined, only messages that match the filters are logged. Otherwise, all
messages at the service level are logged. Infrastructure messages (transactions, peer channel, and
security) are also logged at this level, except for Reliable Messaging messages. On streamed
messages, only the headers are logged. In addition, secure messages are logged decrypted at this
level.
Transport Level
Messages logged at this layer are ready to be encoded or decoded for or after transportation on
the wire. If filters have been defined, only messages that match the filters are logged. Otherwise,
all messages at the transport layer are logged. All infrastructure messages are logged at this
layer, including reliable messaging messages. On streamed messages, only the headers are
logged. In addition, secure messages are logged as encrypted at this level, except if a secure
transport such as HTTPS is used.
Malformed Level
Malformed messages are messages that are rejected by the WCF stack at any stage of processing.
Malformed messages are logged as-is: encrypted if they are so, with non-proper XML, etc.
maxSizeOfMessageToLog defined the size of the message to be logged as CDATA. By default,
maxSizeOfMessageToLog is equal to 256K. For more information of this attribute, see .
Other Options
In addition to the logging levels, the user can specify the following options:
Log Entire Message (logEntireMessage attribute): This value specifies whether the entire
message (message header and body) is logged. The default value is false, meaning that only the
header is logged. This setting affects service and transport message logging levels..
Resource Links for 70-513 WCF Certification Exam
387
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Max messages to log (maxMessagesToLog attribute): This value specifies the maximum
number of messages to log. All messages (service, transport, and malformed messages) are
counted towards this quota. When the quota is reached, a trace is emitted and no additional
message is logged. The default value is 10000.
Max size of message to log (maxSizeOfMessageToLog attribute): This value specifies the
maximum size of messages to log in bytes. Messages that exceed the size limit are not logged,
and no other activity is performed for that message. This setting affects all trace levels. If
ServiceModel tracing is on, a Warning level trace is emitted at the first logging point
(ServiceModelSend* or TransportReceive) to notify the user. The default value for service level
and transport level messages is 256K, while the default value for malformed messages is 4K.
Caution The message size that is computed to compare against maxSizeOfMessageToLog is
the message size in memory before serialization. This size can differ from the actual length of
the message string that is being logged, and in many occasions is bigger than the actual size. As a
result, messages may not be logged. You can account for this fact by specifying the
maxSizeOfMessageToLog attribute to be 10% larger than the expected message size. In
addition, if malformed messages are logged, the actual disk space utilized by the message logs
can be up to 5 times the size of the value specified by maxSizeOfMessageToLog.
If no trace listener is defined in the configuration file, no logging output is generated regardless
of the specified logging level.
Message logging options, such as the attributes described in this section, can be changed at
runtime using Windows Management Instrumentation (WMI). This can be done by accessing the
AppDomainInfo instance, which exposes these Boolean properties:
LogMessagesAtServiceLevel, LogMessagesAtTransportLevel, and
LogMalformedMessages. Therefore, if you configure a trace listener for message logging, but
set these options to false in configuration, you can later change them to true when the
application is running. This will effectively enable message logging at runtime. Similarly, if you
enable message logging in your configuration file, you can disable it at runtime using WMI. For
more information, see Using Windows Management Instrumentation for Diagnostics.
The source field in a message log specifies in which context the message is logged: when
sending/receiving a request message, for a request-reply or 1-way request, at service model or
transport layer, or in the case of a malformed message.
For malformed messages, source is equal to Malformed. Otherwise, source has the following
values based on the context.
For Request/Reply

Send Request Receive Request Send Reply Receive Reply
Service Model layer
Service
Level
Send
Request
Service
Level
Receive
Request
Service
Level
Send
Reply
Service
Level
Receive
Reply
Transport layer
Transport
Send
Transport
Receive
Transport
Send
Transport
Receive
For One-way Request

Send Request Receive Request
Service Model layer Service Service
Resource Links for 70-513 WCF Certification Exam
388
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Level
Send
Datagram
Level
Receive
Datagram
Transport layer
Transport
Send
Transport
Receive
Message Filters
Message filters are defined in the messageLogging configuration element of the diagnostics
configuration section. They are applied at the service and transport level. When one or more
filters are defined, only messages that match at least one of the filters are logged. If no filter is
defined, all messages pass through. Filters support the full XPath syntax, and are applied in the
order they appear in the configuration file. A syntactically incorrect filter results in a
configuration exception.Filters also provide a safety feature using the nodeQuota attribute,
which limits the maximum number of nodes in the XPath DOM that can be examined to match
the filter.The following is an example of how to configure a filter that records only messages that
have a SOAP Header section.
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"
maxMessagesToLog="420">
<filters>
<add nodeQuota="10" xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
/soap:Envelope/soap:Header </add>
</filters>
</messageLogging>
Filters cannot be applied to the body of a message. Filters which attempt to manipulate the body
of a message are removed from the list of filters. An event is also emitted indicating this. For
example, the following filter would be removed from the filter table.
<add
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">/s:Envelope/s:Body[contai
ns(text(), "Hello")]</add>
Configuring a Custom Listener
You can also configure a custom listener with additional options. A custom listener can be useful
in filtering application-specific PII elements from messages before logging. The following
demonstrates a custom listener configuration.
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="MyListener" type="YourCustomListener"
initializeData="c:\logs\messages.svclog" maxDiskSpace="1000"/>
</listeners>
</source>
</sources>
</system.diagnostics>
You should be aware that the type attribute should be set to a qualified assembly name of the
type.
PII Security Lockdown
Resource Links for 70-513 WCF Certification Exam
389
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
This sample demonstrates how to control several security-related features of a Windows
Communication Foundation (WCF) service by:
Encrypting sensitive information in a service's configuration file.
Locking elements in the configuration file so that nested service subdirectories cannot override
settings.
Controlling the logging of Personally Identifiable Information (PII) in trace and message logs.
Important
The samples may already be installed on your computer. Check for the following (default)
directory before continuing.
<InstallDrive>:\WF_WCF_Samples
If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows
Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows
Communication Foundation (WCF) and WF samples. This sample is located in the following
directory.
<InstallDrive>:\WF_WCF_Samples\WCF\Basic\Management\SecurityLockdown
Discussion
Each of these features can be used separately or together to control aspects of a service's security.
This is not a definitive guide to securing a WCF service.The .NET Framework configuration
files can contain sensitive information such as connection strings to connect to databases. In
shared, Web-hosted scenarios it may be desirable to encrypt this information in the configuration
file for a service so that the data contained within the configuration file is resistant to casual
viewing. .NET Framework 2.0 and later has the ability to encrypt portions of the configuration
file using the Windows Data Protection application programming interface (DPAPI) or the RSA
Cryptographic provider. The aspnet_regiis.exe using the DPAPI or RSA can encrypt select
portions of a configuration file.In Web-hosted scenarios it is possible to have services in
subdirectories of other services. The default semantic for determining configuration values
allows configuration files in the nested directories to override the configuration values in the
parent directory. In certain situations this may be undesirable for a variety of reasons. WCF
service configuration supports the locking of configuration values so that nested configuration
generates exceptions when a nested service is run using overridden configuration values.
This sample demonstrates how to control the logging of known Personally Identifiable
Information (PII) in trace and message logs, such as username and password. By default, logging
of known PII is disabled however in certain situations logging of PII can be important in
debugging an application. This sample is based on the Getting Started Sample. In addition, this
sample uses tracing and message logging. For more information, see the Tracing and Message
Logging sample.
Encrypting Configuration File Elements
For security purposes in a shared Web-hosting environment, it may be desirable to encrypt
certain configuration elements, such as database connection strings that may contain sensitive
information. A configuration element may be encrypted using the aspnet_regiis.exe tool found in
the .NET Framework folder For example, %WINDIR%\Micrsoft.NET\Framework\v4.0.20728.
To encrypt the values in the appSettings section in Web.config for the sample
1. Open a command prompt by using Start->Run. Type in cmd and click OK.
2. Navigate to the current .NET Framework directory by issuing the following command: cd
%WINDIR%\Microsoft.NET\Framework\v4.0.20728.
Resource Links for 70-513 WCF Certification Exam
390
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
3. Encrypt the appSettings configuration settings in the Web.config folder by issuing the following
command: aspnet_regiis -pe "appSettings" -app "/servicemodelsamples" -prov
"DataProtectionConfigurationProvider".
More information about encrypting sections of configuration files can be found by reading a
how-to on DPAPI in ASP.NET configuration (Building Secure ASP.NET Applications:
Authentication, Authorization, and Secure Communication) and a how-to on RSA in ASP.NET
configuration (How To: Encrypt Configuration Sections in ASP.NET 2.0 Using RSA).
Locking configuration file elements
In Web-hosted scenarios, it is possible to have services in subdirectories of services. In these
situations, configuration values for the service in the subdirectory are calculated by examining
values in Machine.config and successively merging with any Web.config files in parent
directories moving down the directory tree and finally merging the Web.config file in the
directory that contains the service. The default behavior for most configuration elements is to
allow configuration files in subdirectories to override the values set in parent directories. In
certain situations it may be desirable to prevent configuration files in subdirectories from
overriding values set in parent directory configuration.The .NET Framework provides a way to
lock configuration file elements so that configurations that override locked configuration
elements throw run-time exceptions.A configuration element can be locked by specifying the
lockItem attribute for a node in the configuration file, for example, to lock the
CalculatorServiceBehavior node in the configuration file so that calculator services in nested
configuration files cannot change the behavior, the following configuration can be used.
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior" lockItem="true">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Locking of configuration elements can be more specific. A list of elements can be specified as
the value to the lockElements to lock a set of elements within a collection of sub-elements. A list
of attributes can be specified as the value to the lockAttributes to lock a set of attributes within
an element. An entire collection of elements or attributes can be locked except for a specified list
by specifying the lockAllElementsExcept or lockAllAttributesExcept attributes on a node.
PII Logging Configuration
Logging of PII is controlled by two switches: a computer-wide setting found in Machine.config
that allows a computer administrator to permit or deny logging of PII and an application setting
that allows an application administrator to toggle logging of PII for each source in a Web.config
or App.config file.
The computer-wide setting is controlled by setting enableLoggingKnownPii to true or false, in
the machineSettings element in Machine.config. For example, the following allows applications
to turn on logging of PII.
<configuration>
<system.serviceModel>
Resource Links for 70-513 WCF Certification Exam
391
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<machineSettings enableLoggingKnownPii="true" />
</system.serviceModel>
</configuration>
Note
The Machine.config file has a default location:
%WINDIR%\Microsoft.NET\Framework\v2.0.50727\CONFIG.
If the enableLoggingKnownPii attribute is not present in Machine.config, logging of PII is not
allowed.
Enabling logging of PII for an application is done by setting the logKnownPii attribute of the
source element to true or false in the Web.config or App.config file. For example, the following
enables logging of PII for both message logging and trace logging.
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" logKnownPii="true">
<listeners> ... </listeners>
</source>
<source name="System.ServiceModel" switchValue="Verbose, ActivityTracing">
<listeners> ... </listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
If the logKnownPii attribute is not specified, then PII is not logged.
PII is only logged if both enableLoggingKnownPii is set to true, and logKnownPii is set to true.
Note
System.Diagnostics ignores all attributes on all sources except the first one listed in the
configuration file. Adding the logKnownPii attribute to the second source in the configuration
file has no effect.
Important
To run this sample involves manual modification of Machine.config. Care should be taken when
modifying Machine.config as incorrect values or syntax may prevent all .NET Framework
applications from running.
It is also possible to encrypt configuration file elements using DPAPI and RSA. For more
information, see the following links:
Building Secure ASP.NET Applications: Authentication, Authorization, and Secure
Communication
How To: Encrypt Configuration Sections in ASP.NET 2.0 Using RSA
To set up, build and run the sample
1. Ensure that you have performed the One-Time Setup Procedure for the Windows
Communication Foundation Samples.
2. Edit Machine.config to set the enableLoggingKnownPii attribute to true, adding the parent nodes
if necessary.
3. To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building
the Windows Communication Foundation Samples.
Resource Links for 70-513 WCF Certification Exam
392
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
4. To run the sample in a single- or cross-computer configuration, follow the instructions in
Running the Windows Communication Foundation Samples.
To clean up the sample
Edit Machine.config to set the enableLoggingKnownPii attribute to false.
Configure diagnostics.This objective may include but is not limited to: WMI; performance
counters; event logging
WCF Administration and Diagnostics
Windows Communication Foundation (WCF) provides a rich set of functionalities that can help
you monitor the different stages of an applications life. For example, you can use configuration
to set up services and clients at deployment. WCF includes a large set of performance counters to
help you gauge your application's performance. WCF also exposes inspection data of a service at
runtime through a WCF Windows Management Instrumentation (WMI) provider. When the
application experiences a failure or starts acting improperly, you can use the Event Log to see if
anything significant has occurred. You can also use Message Logging and Tracing to see what
events are happening end-to-end in your application. These features assist both developers and
IT professionals to troubleshoot an WCF application when it is not behaving correctly.
Note:
If you are receiving faults with no specific detail information, you should enable the
includeExceptionDetailInFaults attribute of the <serviceDebug> configuration element. This
instructs WCF to send exception detail to clients, which enables you to detect many common
problems without requiring more advanced diagnosis. For more information, see Sending and
Receiving Faults.
Diagnostics Features Provided by WCF
WCF provides the following diagnostics functionalities:
End-To-End tracing provides instrumentation data for troubleshooting an application without
using a debugger. WCF outputs traces for process milestones, as well as error messages. This can
include opening a channel factory or sending and receiving messages by a service host. Tracing
can be enabled for a running application to monitor its progress. For more information, see the
WCF Tracing topic. To understand how you can use tracing to debug your application, see the
Using Tracing to Troubleshoot Your Application topic.
Message logging allows you to see how messages look both before and after transmission. For
more information, see the WCF Message Logging topic.
Event tracing writes events in the Event Log for any major issues. You can then use the Event
Viewer to examine any abnormalities. For more information, see the WCF Event Logging topic.
Performance counters exposed through Performance Monitor enable you to monitor your
application and system's health. For more information, see the WCF Performance Counters topic.
The System.ServiceModel.Configuration namespace allows you to load configuration files and
set up a service or client endpoint. You can use the object model to script changes to many
applications when updates must be deployed to many computers. Alternatively, you can use the
Configuration Editor to edit the configuration settings using a GUI wizard. For more
information, see the Configuring Your Application topic.
Resource Links for 70-513 WCF Certification Exam
393
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
WMI enables you to find out what services are listening on a machine and the bindings that are
in use. For more information, see the Using Windows Management Instrumentation for
Diagnostics topic.
WCF also provides several GUI and command line tools to make it easier for you to create,
deploy, and manage WCF applications. For more information, see Windows Communication
Foundation Tools. For example, you can use the Service Configuration Editor Tool to create and
edit WCF configuration settings using a wizard, instead of editing XML directly. You can also
use the Service Trace Viewer Tool (SvcTraceViewer.exe) to view, group, and filter trace
messages so that you can diagnose, repair, and verify issues with WCF services.
Using Windows Management
Instrumentation for Diagnostics
Communication Foundation (WCF) exposes inspection data of a service at runtime through a
WCF Windows Management Instrumentation (WMI) provider.
Enabling WMI
WMI is Microsoft's implementation of the Web-Based Enterprise Management (WBEM)
standard. For more information about the WMI SDK, see the MSDN Library.
(http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/wmisdk/wmi/wmi_start_page.asp). WBEM is an industry standard for how applications
expose management instrumentation to external management tools.
A WMI provider is a component that exposes instrumentation at runtime through a WBEM-
compatible interface. It consists of a set of WMI objects that have attribute/value pairs. Pairs can
be of a number of simple types. Management tools can connect to the services through the
interface at runtime. WCF exposes attributes of services such as addresses, bindings, behaviors,
and listeners.
The built-in WMI provider can be activated in the configuration file of the application. This is
done through the wmiProviderEnabled attribute of the <diagnostics> Element in the
system.ServiceModel element section, as shown in the following sample configuration.
<system.serviceModel> <diagnostics wmiProviderEnabled="true" />
</system.serviceModel>
This configuration entry exposes a WMI interface. Management applications can now connect
through this interface and access the management instrumentation of the application.
Accessing WMI Data
WMI data can be accessed in many different ways. Microsoft provides WMI APIs for scripts,
Visual Basic applications, C++ applications, and the .NET Framework. For more information,
see Using WMI.
Caution:
If you use the .NET Framework provided methods to programmatically access WMI data, you should be
aware that such methods may throw exceptions when the connection is established. The connection is
not established during the construction of the ManagementObject instance, but on the first request
involving actual data exchange. Therefore, you should use a try..catch block to catch the possible
exceptions.
Resource Links for 70-513 WCF Certification Exam
394
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
You can change the trace and message logging level, as well as message logging options for the
System.ServiceModel trace source in WMI. This can be done by accessing the AppDomainInfo
instance, which exposes these Boolean properties: LogMessagesAtServiceLevel,
LogMessagesAtTransportLevel, LogMalformedMessages, and TraceLevel. Therefore, if you
configure a trace listener for message logging, but set these options to false in configuration, you
can later change them to true when the application is running. This will effectively enable
message logging at runtime. Similarly, if you enable message logging in your configuration file,
you can disable it at runtime using WMI.You should be aware that if no message logging trace
listeners for message logging, or no System.ServiceModel trace listeners for tracing are
specified in the configuration file, none of your changes are taken into effect, even though the
changes are accepted by WMI. For more information on properly setting up the respective
listeners, see Configuring Message Logging and Configuring Tracing. The trace level of all other
trace sources specified by configuration is effective when the application starts, and cannot be
changed. WCF exposes a GetOperationCounterInstanceName method for scripting. This
method returns a performance counter instance name if you provide it with an operation name.
However, it does not validate your input. Therefore, if you provide an incorrect operation name,
an incorrect counter name is returned. The OutgoingChannel property of the Service instance
does not count channels opened by a service to connect to another service, if the WCF client to
the destination service is not created within the Service method. Caution WMI only supports a
TimeSpan value up to 3 decimal points. For example, if your service sets one of its properties to
MaxValue, its value is truncated after 3 decimal points when viewed through WMI.
Security
Because the WCF WMI provider allows the discovery of services in an environment, you should
exercise extreme caution for granting access to it. If you relax the default administrator-only
access, you may allow less-trusted parties access to sensitive data in your environment.
Specifically, if you loosen permissions on remote WMI access, flooding attacks can occur. If a
process is flooded by excessive WMI requests, its performance can be degraded.In addition, if
you relax access permissions for the MOF file, less-trusted parties can manipulate the behavior
of WMI and alter the objects that are loaded in the WMI schema. For example, fields can be
removed such that critical data is concealed from the administrator or that fields that do not
populate or cause exceptions are added to the file. By default, the WCF WMI provider grants
"execute method", "provider write", and "enable account" permission for Administrator, and
"enable account" permission for ASP.NET, Local Service and Network Service. In particular, on
non-Windows Vista platforms, the ASP.NET account has read access to the WMI ServiceModel
namespace. If you do not want to grant these privileges to a particular user group, you should
either deactivate the WMI provider (it is disabled by default), or disable access for the specific
user group.In addition, when you attempt to enable WMI through configuration, WMI may not
be enabled due to insufficient user privilege. However, no event is written to the event log to
record this failure.
To modify user privilege levels, use the following steps.
1. Click Start and then Run and type compmgmt.msc.
2. Right-click Services and Application/WMI Controls to select Properties.
3. Select the Security Tab, and navigate to the Root/ServiceModel namespace. Click the Security button.
4. Select the specific group or user that you want to control access and use the Allow or Deny checkbox to
configure permissions.
Resource Links for 70-513 WCF Certification Exam
395
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Granting WCF WMI Registration Permissions to Additional
Users
WCF exposes management data to WMI. It does so by hosting an in process WMI provider,
sometimes called a decoupled provider. In order for the management data to be exposed, the
account that registers this provider must have the appropriate permissions. In Windows, only a
small set of privileged accounts can register decoupled providers by default. This is a problem
because users will commonly want to expose WMI data from a WCF service running under an
account that is not in the default set. In order to provide this access, an administrator must grant
the following permissions to the additional account in the following order:
1. Permission to access to the WCF WMI Namespace
2. Permission to register the WCF Decoupled WMI Provider
To grant WMI namespace access permission
1. Run the following PowerShell script.
Windows PowerShell
write-host
write-host Granting Access to root/servicemodel WMI namespace to built in
users group
write-host
# Create the binary representation of the permissions to grant in SDDL
$newPermissions="O:BAG:BAD:P(A;CI;CCDCLCSWRPWPRCWD;;;BA)(A;CI;CC;;;NS)(A;CI;C
C;;;LS)(A;CI;CC;;;BU)"
$converter= new-object system.management.ManagementClass
Win32_SecurityDescriptorHelper
$binarySD=$converter.SDDLToBinarySD($newPermissions)
$convertedPermissions= ,$binarySD.BinarySD
# Get the object used to set the permissions
$security= gwmi -namespace root/servicemodel -class __SystemSecurity
# Get and output the current settings
$binarySD= @($null)
$result=$security.PsBase.InvokeMethod("GetSD",$binarySD)
$outsddl=$converter.BinarySDToSDDL($binarySD[0])
write-host "Previous ACL: "$outsddl.SDDL
# Change the Access Control List (ACL) using SDDL
$result=$security.PsBase.InvokeMethod("SetSD",$convertedPermissions)
# Get and output the current settings
$binarySD= @($null)
$result=$security.PsBase.InvokeMethod("GetSD",$binarySD)
$outsddl=$converter.BinarySDToSDDL($binarySD[0])
write-host "New ACL: "$outsddl.SDDL
write-host
This PowerShell script uses Security Descriptor Definition Language (SDDL) to grant the Built-
In Users group access to the root/servicemodel WMI namespace. It specifies the following
ACLs:
o Built-In Administrator(BA) [Already Had Access]
o Network Service(NS) [Already Had Access]
o Local System(LS) [Already Had Access]
o Built-In Users [The group were granting access to]
To grant provider registration access
1. Run the following PowerShell script.
Resource Links for 70-513 WCF Certification Exam
396
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Windows PowerShell
write-host
write-host Granting WCF provider registration access to built in users
group
write-host
# Set security on ServiceModel provider
$provider= get-WmiObject -namespace "root\servicemodel" __Win32Provider
write-host "Previous ACL: "$provider.SecurityDescriptor
$result=$provider.SecurityDescriptor
="O:BUG:BUD:(A;;0x1;;;BA)(A;;0x1;;;NS)(A;;0x1;;;LS)(A;;0x1;;;BU)"
# Commit the changes and display it to the console
$result=$provider.Put()
write-host "New ACL: "$provider.SecurityDescriptor
write-host
Granting Access to Arbitrary Users or Groups
The example in this section grants WMI Provider registration privileges to all local users. If you
want to grant access to a user or group that is not built in, then you will have to obtain that user
or groups Security Identifier (SID). There is no simple way to get the SID for an arbitrary user.
One method is to logon as the desired user and then issue the following shell command.
Whoami /user
This will provide the SID of the current user, but this method cannot be used to get the SID on
any arbitrary user. Another method to get the SID is to use the getsid.exe tool from the Windows
2000 Resource Kit Tools for administrative tasks. This tool compares the SID of two users (local
or domain), and as a side effect prints the two SIDs to the command line. For more information,
see Well Known SIDs.
Accessing Remote WMI Object Instances
If you need to access WCF WMI instances on a remote machine, you must enable packet privacy
on the tools that you use for access. The following section describes how to achieve these using
the WMI CIM Studio, Windows Management Instrumentation Tester, as well as .NET SDK 2.0.
WMI CIM Studio
If you have installed WMI Administrative Tools, you can use the WMI CIM Studio to access
WMI instances. The tools are in the following folder
%windir%\Program Files\WMI Tools\
1. In the Connect to namespace: window, type root\ServiceModel and click OK.
2. In the WMI CIM Studio Login window, click the Options >> button to expand the window. Select Packet
privacy for Authentication level, and click OK.
Windows Management Instrumentation Tester
This tool is installed by Windows. To run it, launch a command console by typing cmd.exe in
the Start/Run dialog box and click OK. Then, type wbemtest.exe in the command window. The
Windows Management Instrumentation Tester tool is then launched.
1. Click the Connect button on the top right corner of the window.
2. In the new window, enter root\ServiceModel for the Namespace field, and select Packet privacy for
Authentication level. Click Connect.
Using Managed Code
You can also access remote WMI instances programmatically by using classes provided by the
System.Management namespace. The following code sample demonstrates how to do this.
String wcfNamespace = String.Format(@"\\{0}\Root\ServiceModel",
this.serviceMachineName);
Resource Links for 70-513 WCF Certification Exam
397
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
ConnectionOptions connection = new ConnectionOptions();
connection.Authentication = AuthenticationLevel.PacketPrivacy;
ManagementScope scope = new ManagementScope(this.wcfNamespace, connection);
WCF Performance Counters
Windows Communication Foundation (WCF) includes a large set of performance counters to
help you gauge your application's performance.
Enabling Performance Counters
You can enable performance counters for a WCF service through the app.config configuration
file of the WCF service as follows:
<configuration>
<system.serviceModel>
<diagnostics performanceCounters="All" />
</system.serviceModel>
</configuration>
The performanceCounters attribute can be set to enable a specific type of performance
counters. Valid values are
All: All category counters (ServiceModelService, ServiceModelEndpoint and
ServiceModelOperation) are enabled.
ServiceOnly: Only ServiceModelService category counters are enabled.
Off: ServiceModel* performance counters are disabled. This is the default value.
If you want to enable performance counters for all WCF applications, you can place the
configuration settings in the Machine.config file. Please see the section for more information on
configuring sufficient memory for performance counters on your machine.
You can also enable performance counters in your code as follows,
using System.Configuration;
using System.ServiceModel.Configuration;
using System.ServiceModel.Diagnostics;
Configuration config = ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None);
ServiceModelSectionGroup sg =
ServiceModelSectionGroup.GetSectionGroup(config);
sg.Diagnostic.PerformanceCounters = PerformanceCounterScope.All;
config.Save();
Viewing Performance Data
To view data captured by the performance counters, you can use the Performance Monitor
(Perfmon.exe) that comes with Windows. You can launch this tool by going to Start, and click
Run and type perfmon.exe in the dialog box.
Note:
Performance counter instances may be released before the last messages have been processed by
the endpoint dispatcher. This can result in performance data not being captured for a few
messages.
Increasing Memory Size for Performance Counters
WCF uses separate shared memory for its performance counter categories.
By default, separate shared memory is set to a quarter the size of global performance counter
memory. The default global performance counter memory is 524,288 bytes. Therefore, the three
WCF performance counter categories have a default size of approximately 128KB each.
Resource Links for 70-513 WCF Certification Exam
398
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Depending upon the runtime characteristics of the WCF applications on a machine, performance
counter memory may be exhausted. When this happens, WCF writes an error to the application
event log. The content of the error states that a performance counter was not loaded, and the
entry contains the exception "System.InvalidOperationException: Custom counters file view is
out of memory." If tracing is enabled at the error level, this failure is also traced. If performance
counter memory is exhausted, continuing to run your WCF applications with performance
counters enabled could result in performance degradation. If you are an administrator of the
machine, you should configure it to allocate enough memory to support the maximum number of
performance counters that can exist at any time. For more information, see.performanceCounters
You can change the amount of performance counter memory for WCF categories in the registry.
To do so, you need to add a new DWORD value named FileMappingSize to the three following
locations, and set it to the desired value in bytes. Reboot your machine so that these changes are
taken into effect.
HKLM\System\CurrentControlSet\Services\ServiceModelEndpoint 3.0.0.0\Performance
HKLM\System\CurrentControlSet\Services\ServiceModelOperation 3.0.0.0\Performance
HKLM\System\CurrentControlSet\Services\ServiceModelService 3.0.0.0\Performance
When a large number of objects (e.g., ServiceHost) are disposed of but waiting to be garbage-
collected, the PrivateBytes performance counter will register an unusually high number. To
resolve this problem, you can either add your own application-specific counters, or use the
performanceCounters attribute to enable only service-level counters.
Types of Performance Counters
Performance counters are scoped to three different levels: Service, Endpoint and Operation.
You can use WMI to retrieve the name of a performance counter instance. For example,
Service counter instance name can be obtained through WMI Service instance's
"CounterInstanceName" property.
Endpoint counter instance name can be obtained through WMI Endpoint instance's
"CounterInstanceName" property.
Operation counter instance name can be obtained through WMI Endpoint instance's
"GetOperationCounterInstanceName" method.
For more information on WMI, see Using Windows Management Instrumentation for
Diagnostics.
Service performance counters
Service performance counters measure the service behavior as a whole and can be used to
diagnose the performance of the whole service. They can be found under the
ServiceModelService 3.0.0.0 performance object when viewing with Performance Monitor. The
instances are named using the following pattern:ServiceName@ServiceBaseAddress
A counter in a service scope is aggregated from counter in a collection of endpoints.
Performance counters for service instance creation are incremented when a new InstanceContext
is created. Note that a new InstanceContext is created even when you receive a non-activating
message (with an existing service), or when you connect to an instance from one session, end the
session, and then reconnect from another session.
Endpoint performance counters
Endpoint performance counters enable you to look at data reflecting how an endpoint is
accepting messages. They can be found under the ServiceModelEndpoint 3.0.0.0 performance
Resource Links for 70-513 WCF Certification Exam
399
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
object when viewing using the Performance Monitor. The instances are named using the
following pattern:(ServiceName).(ContractName)@(endpoint listener address)
The data is similar to what is collected for individual operations, but is only aggregated across
the endpoint. A counter in an endpoint scope is aggregated from counters in a collection of
operations.
Note:
If two endpoints have identical contract names and addresses, they are mapped to the same
counter instance.
Operation performance counters
Operation performance counters are found under the ServiceModelOperation 3.0.0.0
performance object when viewing with the Performance Monitor. Each operation has an
individual instance. That is, if a given contract has 10 operations, 10 operation counter instances
are associated with that contract. The object instances are named using the following pattern:
(ServiceName).(ContractName).(OperationName)@(first endpoint listener
address)
This counter enables you to measure how the call is being used and how well the operation is
performing.When counters are visible at multiple scopes, data gathered from a higher scope are
aggregated with data from lower scopes. For example, Calls at an endpoint represents the sum of
all operation calls within the endpoint; Calls at a service represents the sum of all calls to all
endpoints within the service.
Note:
If you have duplicate operation names on a contract, you only get one counter instances for both
operations.
Programming the WCF Performance Counters
Several files are installed in the SDK install folder so that you can access the WCF performance
counters programmatically. These files are listed as follows.
_ServiceModelEndpointPerfCounters.vrg
_ServiceModelOperationPerfCounters.vrg
_ServiceModelServicePerfCounters.vrg
_SMSvcHostPerfCounters.vrg
_TransactionBridgePerfCounters.vrg
For more information on how to access the counters programmatically, see Performance Counter
Programming Architecture.
WCF Event Logging
Windows Communication Foundation (WCF) traces internal events in the Windows event log.
Viewing Event Logs
Event logging is enabled automatically by default, and there is no mechanism to disable it.
Events logged by WCF can be viewed using the Event Viewer. To launch this tool, click Start,
click Control Panel, double-click Administrative Tools, and then double-click Event Viewer.
Application Event LogThe Application Event Log contains most of the events generated by
WCF. Most of the entries indicate that a particular feature failed to start up for an application.
Examples include:
Resource Links for 70-513 WCF Certification Exam
400
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Message Logging/tracing: WCF writes an event to the event log when trace and message logging
fails. However, not every trace failure triggers an event. To prevent the event log from being
completely filled with traces failures, WCF implements a 10 minute blackout period for such an
event. This means that if WCF writes a trace failure to the event log, it will not do so again for at
least 10 minutes.
Shared Listener: The WCF TCP Port Sharing Service logs an event when it fails to start.
CardSpace: Logs events when the service fails to start.
Critical and error events, such as startup failures or crashes
Message logging turned on: Logs events when message logging is turned on. This is to notify the
administrator that sensitive, application-specific information may be logged in message headers
and bodies.
An event is logged when the enableLoggingKnownPII attribute in the machineSettings
element of the machine.config file is set. This attribute specifies if any application running on
the machine is permitted to log known personally identifiable information (PII).
If the logKnownPii attribute in either the app.config or web.config file is set to true for a
specific application to turn on PII logging, but the enableLoggingKnownPII attribute in the
machineSettings element of the machine.config file is set to false, an event is logged. In
addition, if both logKnownPii and enableLoggingKnownPII are set to true, and event is
logged. For more information on these configuration settings, see the Security section of the
Configuring Message Logging topic.
Security Event Log
The Security Event Log contains security audit events that are logged by WCF.
System Event Log
WCF does not log anything in the System Event Log.
Event Log Entries
The source of an event is the name of the assembly that generates the log entry.
The type of an event log entry is used to indicate the severity of an event. Each event must be of
a single type, which the application indicates when it reports the event. The Event Viewer uses
this type to determine which icon to display in the list view of the log. For the different event
type of an event log entry, see EventLogEntryType.
When you click more information when viewing an event in the Event Viewer, the Event
Viewer may send information across the Internet. For more information, see the Event Viewer
help.
Debug client-service interactions.This objective may include but is not limited to: sending server
exception details to client; end-to-end tracing; interpreting output from the trace viewer (single
message and end to end)This objective does not include: tracing viewer features outside of
viewing traces
End-to-End Tracing in WCF
End to End (e2e) Tracing allows developers to follow the execution of code in the Windows
Communication Foundation (WCF) infrastructure to investigate why a code path has failed, or to
provide detailed tracing for capacity planning and performance analysis. Windows
Communication Foundation (WCF) provides three correlation mechanisms to help diagnose the
cause of an error: activities, transfers, and propagation.
Resource Links for 70-513 WCF Certification Exam
401
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
See End-To-End Tracing Scenarios for a list of end-to-end tracing scenarios, and their respective
activity and tracing design.
Activity Describes activity traces in the Windows Communication Foundation (WCF) tracing
model.
Transfer Describes transfer in the Windows Communication Foundation (WCF) tracing model,
and using transfer to correlate activities within endpoints.
Propagation Describes activity propagation in the Windows Communication Foundation (WCF)
tracing model, and using propagation to correlate activities across endpoints.
Trace Type Summary Provides a summary of all activity trace types
Activity
This topic describes activity traces in the Windows Communication Foundation (WCF) tracing
model. Activities are processing units that help the user narrow down the scope of a failure.
Errors that occur in the same activity are directly related. For example, an operation fails because
message decryption has failed. The traces for both the operation and message decryption failure
appear in the same activity, showing direct correlation between the decryption error and the
request error.
Configuring Activity Tracing
WCF provides pre-defined activities for processing applications (see Activity List). You can also
define activities programmatically to group user traces. For more information, see Emitting User-
Code Traces.
To emit activity traces at run time, use the ActivityTracing setting for the
System.ServiceModel trace source, or other WCF or custom trace sources, as demonstrated by
the following configuration code.
<source name="System.ServiceModel" switchValue="Verbose,ActivityTracing">
To understand more about the configuration element and attributes being used, see the
Configuring Tracing topic.
Viewing Activities
You can view the activities and their utility in the Service Trace Viewer Tool. When
ActivityTracing is enabled, this tool takes the traces and sorts them based on activity. You can
also see trace transfers. A trace transfer indicates how different activities are related to each
other. You can see that a particular activity caused another to start. For example, a message
request started a security handshake to get a Secure Conversation Token.
Correlating Activities in Service Trace Viewer
The Service Trace Viewer tool provides two views of activities:
List view, where the activity ID is used to directly correlate traces across processes. Traces from
different processes, e.g., client and service, but with the same activity ID are grouped in the same
activity. Therefore, an error occurring on the service which then causes an error on the client will
both show up in the same activity view in the tool.
Graph view, where activities are grouped by processes. In this view, a client and service with
the same activity ID have their traces in different activities. To correlate activities with the same
activity ID in different processes, the tool shows message flows across the related activities.
For more information, and to see a graphical view of the Service Trace Viewer tool, see Service
Trace Viewer Tool and Using Service Trace Viewer for Viewing Correlated Traces and
Troubleshooting.
Resource Links for 70-513 WCF Certification Exam
402
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Defining the Scope of an Activity
An activity is defined at design time and denotes a logical unit of work. Emitted traces with the
same activity identifier are directly related, they are part of the same activity. Because an activity
can cross endpoint boundaries (e.g., a request), two scopes for an activity are defined.
Global scope, per application. In this scope, the activity is identified by its 128-bit globally
unique activity identifier, the gAId. The gAid is what is propagated across endpoints.
Local scope, per endpoint. In this scope, the activity is identified by its gAId, along with the
trace source name emitting the activity traces and the process Id. This triplet constitutes the local
activity id, lAId. The lAId is used to define the (local) boundaries of an activit y.
Trace Schema
Traces can be emitted using any schema, and across Microsoft platforms. e2e (for End to
End) is a commonly used schema. This schema includes a 128 bit identifier (gAId), the trace
source name, and process ID. In managed code, XmlWriterTraceListener emits traces in the E2E
schema.
Developers can set the AID that is emitted with a trace by setting the ActivityId property with a
Guid on Thread Local Storage (TLS). The following example demonstrates this.
// set the current Activity ID to a new GUID.
CorrelationManager.ActivityId = Guid.NewGuid();
Setting the gAId in TLS will be evident when traces are emitted using a trace source, as shown
by the following example.
TraceSource traceSource = new TraceSource("myTraceSource");
traceSource.TraceEvent(TraceEventType.Warning, eventId, "Information");
The trace emitted will contain the gAId currently in TLS, the trace source name passed as a
parameter to the trace sources constructor, and the current processs ID.
Activity Lifetime
In strictest terms, evidence of an activity starts the first time the activity ID is used in an emitted
trace, and ends the last time it is used in an emitted trace. A predefined set of trace types are
provided by System.Diagnostics, including Start and Stop, to explicitly mark the activity lifetime
boundaries.
Start: Indicates the beginning of an activity. A Start trace provides a record of beginning a new
processing milestone. It contains a new activity ID for a given trace source in a given process,
except when the activity ID is propagated across endpoints, in which case we see one "Start" per
endpoint. Examples of starting a new activity include creating a new thread for processing, or
entering a new public method.
Stop: Indicates the end of an activity. A Stop trace provides a record of ending an existing
processing milestone. It contains an existing activity ID for a given trace source in a given
process, except when the activity ID is propagated across endpoints, in which case we see one
"Stop" per endpoint. Examples of stopping an activity include terminating a processing thread, or
exiting a method whose beginning was denoted with a Start trace.
Suspend: Indicates suspension of processing of an activity. A Suspend trace contains an
existing activity ID whose processing is expected to resume at a later time. No traces are emitted
with this ID between the Suspend and Resume events from the current trace source. Examples
include pausing an activity when calling into an external library function, or when waiting on a
resource such as an I/O completion port.
Resource Links for 70-513 WCF Certification Exam
403
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Resume: Indicates the resumption of processing of an activity. A Resume trace contains an
existing activity id whose last emitted trace from the current trace source was a Suspend trace.
Examples include returning from a call to an external library function, or when signaled to
resume processing by a resource such as an I/O completion port.
Transfer: Because some activities are caused by others, or relate to others, activities can be
related to other activities through Transfer traces. A transfer records the directed relationship
of one activity to another
Start and Stop traces are not critical for correlation. However, they can help in increasing
performance, profiling, and activity scope validation.
Using these types, the tools can optimize navigating the trace logs to find the immediately related
events of the same activity, or events in related activities if the tool follows transfer traces. For
example, the tools will stop parsing the logs for a given activity when they see a Start/Stop trace.
These trace types can also be used for profiling. Resources consumed between the start and stop
markers represent the activitys inclusive time including contained logical activities. Subtracting
the time intervals between the Suspend and Resume traces provides the actual activity time.
The Stop trace is also particularly useful for validating the scope of the implemented activities. If
some processing traces appear after the Stop trace instead of inside a given activity, this can
suggests code defect.
Guidelines for Using Activity Tracing
The following is a guideline of using ActivityTracing traces (Start, Stop, Suspend, Resume, and
Transfer).
Tracing is a directed cyclic graph, not a tree. You can return control to an activity which
spawned an activity.
An activity denotes a processing boundary which can be meaningful to the administrator of the
system or for supportability.
Each WCF method, both on the client and server, is bounded by beginning a new activity, then
(after work is done) ending the new activity and returning to the ambient activity.
Long running (ongoing) activities such as listening for connections or waiting for messages are
represented by corresponding start/stop markers.
Activities triggered by the receipt or processing of a message are represented by trace
boundaries.
Activities represent activities, not necessarily objects. An activity should be interpreted as this
was happening when . . . (meaningful trace emission occurred)."
Transfer
.NET Framework 3.5
This topic describes transfer in the Windows Communication Foundation (WCF) activity tracing
model.
Transfer Definition
Transfers between activities represent causal relationships between events in the related activities
within endpoints. Two activities are related with transfers when control flows between these
activities, e.g., a method call crossing activity boundaries. In WCF, when bytes are incoming on
the service, the Listen At activity is transferred to the Receive Bytes activity where the message
object is created. For a list of end-to-end tracing scenarios, and their respective activity and
tracing design, see End-To-End Tracing Scenarios.
Resource Links for 70-513 WCF Certification Exam
404
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
To emit transfer traces, use the ActivityTracing setting on the trace source as demonstrated by
the following configuration code.
<source name="System.ServiceModel" switchValue="Verbose,ActivityTracing">
Using Transfer to Correlate Activities Within Endpoints
Activities and transfers permit the user to probabilistically locate the root cause of an error. For
example, if we transfer back and forth between activities M and N respectively in components M
and N, and a crash happens in N right after the transfer back to M, we can draw the conclusion
that it is likely due to Ns passing data back to M.
A transfer trace is emitted from activity M to activity N when there is a flow of control between
M and N. For example, N performs some work for M because of a method call crossing the
activities boundaries. N may already exist or has been created. N is spawned by M when N is a
new activity that performs some work for M.
A transfer from M to N may not be followed by a transfer back from N to M. This is because M
can spawn some work in N and do not track when N completes that work. In fact, M can
terminate before N completes its task. This happens in the Open ServiceHost activity (M) that
spawns Listener activities (N) and then terminates. A transfer back from N to M means that N
completed the work related to M.
N can continue performing other processing unrelated to M, e.g., an existing authenticator
activity (N) that keeps receiving login requests (M) from different login activities.
A nesting relationship does not necessarily exist between activities M and N. This can happen
due to two reasons. First, when activity M does not monitor the actual processing performed in N
although M initiated N. Second, when N already exists.
Example of Transfers
The following lists two transfer examples.
When you create a service host, the constructor gains control from the calling code, or the calling
code transfers to the constructor. When the constructor has finished executing, it returns control
to the calling code, or the constructor transfers back to the calling code. This is the case of a
nested relationship.
When a listener starts processing transport data, it creates a new thread and hands to the Receive
Bytes activity the appropriate context for processing, i.e., passing control and data. When that
thread has finished processing the request, the Receive Bytes activity passes nothing back to the
listener. In this case, we have a transfer in but no transfer out of the new thread activity. The two
activities are related but not nested.
Activity Transfer Sequence
A well-formed activity transfer sequence includes the following steps.
1. Begin a new activity, which consists of selecting a new gAId.
2. Emit a transfer trace to that new gAId from the current activity ID
3. Set the new ID in TLS
4. Emit a start trace to indicate the beginning of the new activity by.
5. Return to the original activity consists of the following:
6. Emit a transfer trace to the original gAId
7. Emit a Stop trace to indicate the end of the new activity
8. Set TLS to the old gAId.
Resource Links for 70-513 WCF Certification Exam
405
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The following code example demonstrates how to do this. This sample assumes a blocking call is
made when transferring to the new activity, and includes suspend/resume traces.
// 0. Create a trace source
TraceSource ts = new TraceSource(myTS);
// 1. remember existing (ambient) activity for clean up
Guid oldGuid = Trace.CorrelationManager.ActivityId;
// this will be our new activity
Guid newGuid = Guid.NewGuid();
// 2. call transfer, indicating that we are switching to the new AID
ts.TraceTransfer(667, "Transferring.", newGuid);
// 3. Suspend the current activity.
ts.TraceEvent(TraceEventType.Suspend, 667, "Suspend: Activity " + i-1);
// 4. set the new AID in TLS
Trace.CorrelationManager.ActivityId = newGuid;
// 5. Emit the start trace
ts.TraceEvent(TraceEventType.Start, 667, "Boundary: Activity " + i);
// trace something
ts.TraceEvent(TraceEventType.Information, 667, "Hello from activity " + i);
// Perform Work
// some work.
// Return
ts.TraceEvent(TraceEventType.Information, 667, "Work complete on activity " +
i);
// 6. Emit the transfer returning to the original activity
ts.TraceTransfer(667, "Transferring Back.", oldGuid);
// 7. Emit the End trace
ts.TraceEvent(TraceEventType.Stop, 667, "Boundary: Activity " + i);
// 8. Change the tls variable to the original AID
Trace.CorrelationManager.ActivityId = oldGuid;
// 9. Resume the old activity
ts.TraceEvent(TraceEventType.Resume, 667, "Resume: Activity " + i-1);
Propagation
This topic describes activity propagation in the Windows Communication Foundation (WCF)
tracing model.
Using Propagation to Correlate Activities Across Endpoints
Propagation provides the user with direct correlation of error traces for the same unit of
processing across application endpoints, e.g., a request. Errors emitted at different endpoints for
the same unit of processing are grouped in the same activity, even across application domains.
This is done through propagation of the activity ID in the message headers. Therefore, if a client
times out because of an internal error in the server, both errors appear in the same activity for
direct correlation.
To do this, use the ActivityTracing setting as demonstrated in the previous example. In addition,
set the propagateActivity attribute for the System.ServiceModel trace source at all endpoints.
<source name="System.ServiceModel" switchValue="Verbose,ActivityTracing"
propagateActivity=true >
Activity propagation is a configurable capability that causes WCF to add a header to outbound
messages, which includes the activity ID on the TLS. By including this on subsequent traces on
the server side, we can correlate client and server activities.
Propagation Definition
Resource Links for 70-513 WCF Certification Exam
406
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Activity Ms gAId is propagated to activity N if all of the following conditions apply.
N is created because of M
Ms gAId is known to N
N's gAId is equal to Ms gAId.
The gAId is propagated through the ActivityId message header, as illustrated in the following
XML schema.
<xsd:element name=ActivityId type=integer minOccurs=0>
<xsd:attribute name=CorrelationId type=integer minOccurs=0/>
</xsd:element>
The following is an example of the message header.
<MessageLogTraceRecord>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action
s:mustUnderstand="1">http://Microsoft.ServiceModel.Samples/ICalculator/Subtra
ct
</a:Action>
<a:MessageID>urn:uuid:f0091eae-d339-4c7e-9408-ece34602f1ce
</a:MessageID>
<ActivityId CorrelationId="f94c6af1-7d5d-4295-b693-4670a8a0ce34"
xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">
17f59a29-b435-4a15-bf7b-642ffc40eac8
</ActivityId>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous
</a:Address>
</a:ReplyTo>
<a:To
s:mustUnderstand="1">net.tcp://localhost/servicemodelsamples/service</a:To>
</s:Header>
<s:Body>
<Subtract xmlns="http://Microsoft.ServiceModel.Samples">
<n1>145</n1>
<n2>76.54</n2>
</Subtract>
</s:Body>
</s:Envelope>
</MessageLogTraceRecord>
Propagation and Activity Boundaries
When the activity ID is propagated across endpoints, the message receiver emits a Start and Stop
traces with that (propagated) activity ID. Therefore, there is a Start and Stop trace with that gAId
from each trace source. If the endpoints are in the same process and use the same trace source
name, multiple Start and Stop with the same lAId (same gAId, same trace source, same process)
are created.
Synchronization
To synchronize events across endpoints that run on different machines, e.g., message
sent/message received, a CorrelationId is added to the ActivityId header that is propagated in
messages. Tools can use this ID to synchronize events across machines with clock discrepancy.
Resource Links for 70-513 WCF Certification Exam
407
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Specifically, the Service Trace Viewer tool uses this ID for showing message flows between
endpoints.
Trace Type Summary
Source Levels defines various trace levels: Critical, Error, Warning, Information, and Verbose,
as well as provides description of the ActivityTracing flag, which toggles the output of trace
boundary and activity transfer events.
You can also review TraceEventType for the types of traces which can be emitted from
System.Diagnostics.
The following table lists the most important ones.
Trace Type Description
Critical Fatal error or application crash.
Error Recoverable error.
Warning Informational message.
Information Non-critical problem.
Verbose Debugging trace.
Start Starting of a logical unit of processing.
Suspend Suspension of a logical unit of processing.
Resume Resumption of a logical unit of processing.
Stop Stopping of a logical unit of processing.
Transfer Changing of correlation identity.
An activity is defined as a combination of the trace types above.
The following is a regular expression that defines an ideal activity in a local (trace source) scope,
R = Start (Critical | Error | Warning | Information | Verbose | Transfer |
(Transfer Suspend Transfer Resume) )* Stop
This means that an activity must satisfy the following conditions.
It must start and stop respectively by a Start and Stop traces
It must have a Transfer trace immediately preceding a Suspend or Resume trace
It must not have any traces between the Suspend and Resume traces if such traces exist
It can have any and as many of critical/Error/Warning/Information/Verbose/Transfer traces as
long as the previous conditions are observed
The following is a regular expression that defines an ideal activity in the global scope,
R+
with R being the regular expression for an activity in the local scope. This translates to,
[R+ = Start ( Critical | Error | Warning | Information | Verbose | Transfer |
(Transfer Suspend Transfer Resume) )* Stop]+
Using Service Trace Viewer for Viewing
Correlated Traces and Troubleshooting
This topic describes the format of trace data, how to view it, and approaches that use the Service
Trace Viewer to troubleshoot your application.
Using the Service Trace Viewer Tool
Resource Links for 70-513 WCF Certification Exam
408
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
The Windows Communication Foundation (WCF) Service Trace Viewer tool helps you correlate
diagnostic traces produced by WCF listeners to locate the root cause of an error. The tool gives
you a way to easily view, group, and filter traces so that you can diagnose, repair and verify
issues with WCF services. For more information about using this tool, see Service Trace Viewer
Tool.
This topic contains screenshots of traces generated by running the Tracing and Message Logging
sample, when viewed using the Service Trace Viewer Tool. This topic demonstrates how to
understand trace content, activities and their correlation, and how to analyze large numbers of
traces when troubleshooting.
Viewing Trace Content
A trace event contains the following most significant information:
Activity name when set.
Emission time.
Trace level.
Trace source name.
Process name.
Thread id.
A unique trace identifier, which is a URL that points to a destination in the online MSDN library,
from which you can obtain more information related to the trace.
All of these can be seen in the upper right panel in the Service Trace Viewer, or in the Basic
Information section in the formatted view of the lower-right panel when selecting a trace.
In addition, the formatted view also provides a description for the trace and additional detailed
information when available. The latter can include exception type and message, call stacks,
message action, from/to fields, and other exception information.
In the XML view, useful xml tags include the following:
<SubType> (trace level).
<TimeCreated>.
<Source> (trace source name).
<Correlation> (activity id set when emitting the trace).
<Execution> (process and thread id).
<Computer>.
<ExtendedData>, including <Action>, <MessageID> and the <ActivityId> set in the message
header when sending a message.
If you examine the "Sent a message over a channel" trace, you may see the following content.
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>262163</EventID>
<Type>3</Type>
<SubType Name="Information">0</SubType>
<Level>8</Level>
<TimeCreated SystemTime="2006-08-04T18:45:30.8491051Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{27c6331d-8998-43aa-a382-03239013a6bd}"/>
<Execution ProcessName="client" ProcessID="1808" ThreadID="1" />
<Channel />
<Computer>TEST1</Computer>
</System>
<ApplicationData>
Resource Links for 70-513 WCF Certification Exam
409
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
<TraceData>
<DataItem>
<TraceRecord
xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord"
Severity="Information">
<TraceIdentifier>http://msdn.microsoft.com/en-
US/library/System.ServiceModel.Channels.MessageSent.aspx</TraceIdentifier>
<Description>Sent a message over a channel.</Description>
<AppDomain>client.exe</AppDomain>
<Source>System.ServiceModel.Channels.ClientFramingDuplexSessionChannel/351911
96</Source>
<ExtendedData
xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/MessageTransmitTrace
Record">

<MessageProperties>
<AllowOutputBatching>False</AllowOutputBatching>
</MessageProperties>
<MessageHeaders>
<Action d4p1:mustUnderstand="1" xmlns:d4p1="http://www.w3.org/2003/05/soap-
envelope"
xmlns="http://www.w3.org/2005/08/addressing">http://Microsoft.ServiceModel.Sa
mples/ICalculator/Multiply</Action>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:7c6670d8-
4c9c-496e-b6a0-2ceb6db35338</MessageID>
<ActivityId CorrelationId="b02e2189-0816-4387-980c-dd8e306440f5"
xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">27c6331
d-8998-43aa-a382-03239013a6bd</ActivityId>
<ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
<To d4p1:mustUnderstand="1" xmlns:d4p1="http://www.w3.org/2003/05/soap-
envelope"
xmlns="http://www.w3.org/2005/08/addressing">net.tcp://localhost/servicemodel
samples/service</To>
</MessageHeaders>
<RemoteAddress>net.tcp://localhost/servicemodelsamples/service</RemoteAddress
>
</ExtendedData>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
ServiceModel E2E Tracing
When the System.ServiceModel trace source is set with a switchValue other than Off, and
ActivityTracing, WCF creates activities and transfers for WCF processing.
An activity is a logical unit of processing that groups all traces related to that processing unit. For
example, you can define one activity for each request. Transfers create a causal relationship
between activities within endpoints. Propagating the activity ID enables you to relate activities
across endpoints. This can be done by setting propagateActivity=true in configuration at every
endpoint. Activities, transfers, and propagation allow you to perform error correlation. In this
way, you can find the root cause of an error more quickly.
Resource Links for 70-513 WCF Certification Exam
410
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
On the client, one WCF activity is created for each object model call (for example, Open
ChannelFactory, Add, Divide, and so on.) Each of the operation calls is processed in a Process
Action activity.
In the following screenshot, extracted from the Tracing and Message Logging sample the left
panel displays the list of activities created in the client process, sorted by creation time. The
following is a chronological list of activities:
Constructed the channel factory (ClientBase).
Opened the channel factory.
Processed the Add action.
Set up the Secure Session (this OCCURRED on the first request) and processed three security
infrastructure response messages: RST, RSTR, SCT (Process message 1, 2, 3).
Processed the Subtract, Multiply, and Divide requests.
Closed the channel factory, and doing so closed the Secure session and processed the security
message response Cancel.
We see the security infrastructure messages because of the wsHttpBinding.
Note:
In WCF, we show response messages being processed initially in a separate activity (Process
message) before we correlate them to the corresponding Process Action activity that includes the
request message, through a transfer. This happens for infrastructure messages and asynchronous
requests and is due to the fact that we must inspect the message, read the activityId header, and
identify the existing Process Action activity with that id to correlate to it. For synchronous
requests, we are blocking for the response and hence know which Process action the response
relates to.

When we select an activity in the left panel, we can see nested activities and traces on the upper
right panel. Therefore, this is a reduced hierarchical view of the list of activities on the left, based
on the selected parent activity. Because the selected Process action Add is the first request made,
Resource Links for 70-513 WCF Certification Exam
411
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
this activity contains the Set Up Secure Session activity (transfer to, transfer back from), and
traces for the actual processing of the Add action.
If we double click the Process action Add activity in the left panel, we can see a graphical
representation of the client WCF activities related to Add. The first activity on the left is the root
activity (0000), which is the default activity. WCF transfers out of the ambient activity. If this is
not defined, WCF transfers out of 0000. Here, the second activity, Process Action Add, transfers
out of 0. Then we see Setup Secure Session.

On the upper right panel, we can see all traces related to the Process Action Add activity.
Specifically, we have sent the request message ("Sent a message over a channel") and received
the response ("Received a message over a channel") in the same activity. This is shown in the
following graph. For clarity, the Set up Secure Session activity is collapsed in the graph.
Resource Links for 70-513 WCF Certification Exam
412
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

Resource Links for 70-513 WCF Certification Exam
413
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/
Here, we load client traces only for clarity, but service traces (request message received and
response message sent) appear in the same activity if they are also loaded in the tool and
propagateActivity was set to true. This is shown in a later illustration.
On the service, the activity model maps to the WCF concepts as follows:
1. We construct and open a ServiceHost (this may create several host-related activities, for
instance, in the case of security).
2. We create a Listen At activity for each listener in the ServiceHost (with transfers in and out of
Open ServiceHost).
3. When the listener detects a communication request initiated by the client, it transfers to a
Receive Bytes activity, in which all bytes sent from the client are processed. In this activity,
we can see any connection errors that have happened during the client-service interaction.
4. For each set of bytes that is received that corresponds to a message, we process these bytes in a
Process Message activity, where we create the WCF Message object. In this activity, we see
errors related to a bad envelope or a malformed message.
5. Once the message is formed, we transfer to a Process Action activity. If propagateActivity is set
to true on both the client and service, this activity has the same id as the one defined in the
client, and described previously. From this stage we start to benefit from direct correlation across
endpoints, because all traces emitted in WCF that are related to the request are in that same
activity, including the response message processing.
6. For out-of-process action, we create an Execute user code activity to isolate traces emitted in
user code from the ones emitted in WCF. In the preceding example, the Service sends Add
response trace is emitted in the Execute User code activity not in the activity propagated by
the client, if applicable.
In the illustration that follows, the first activity on the left is the root activity (0000), which is the
default activity. The next three activities are to open the ServiceHost. The activity in column 5 is
the listener, and the remaining activities (6 to 8) describe the WCF processing of a message,
from bytes processing to user code activation.
Resource Links for 70-513 WCF Certification Exam
414
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

The following screenshot shows the activities for both the client and service, and highlights the
Process Action Add activity across processes (orange). Arrows relate the request and response
messages sent and received by the client and service. The traces of Process Action are separated
across processes in the graph, but shown as part of the same activity in the upper-right panel. In
this panel, we can see client traces for sent messages followed by service traces for received and
processed messages.
Resource Links for 70-513 WCF Certification Exam
415
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

In the following error scenario, error and warning traces at the service and client are related. An
exception is first thrown in user code on the service (right-most green activity that includes a
warning trace for the exception "The service cannot process this request in user code."). When
the response is sent to the client, a warning trace is again emitted to denote the fault message
(left pink activity). The client then closes its WCF client (yellow activity on the lower-left side),
which aborts the connection to the service. The service throws an error (longest pink activity on
the right).
Resource Links for 70-513 WCF Certification Exam
416
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

The sample used to generate these traces is a series of synchronous requests using the
wsHttpBinding. There are deviations from this graph for scenarios without security, or with
asynchronous requests, where the Process Action activity encompasses the begin and end
operations that constitute the asynchronous call, and shows transfers to a callback activity. For
more information about additional scenarios, see End-To-End Tracing Scenarios.
Troubleshooting Using the Service Trace Viewer
When you load trace files in the Service Trace Viewer Tool, you can select any red or yellow
activity on the left panel to track down the cause of a problem in your application. The 000
activity typically has unhandled exceptions that bubble up to the user.
Resource Links for 70-513 WCF Certification Exam
417
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

On the upper right panel, you can examine traces for the activity you selected on the left. You
can then examine red or yellow traces in that panel and see how they are correlated. In the
preceding graph, we see warning traces both for the client and service in the same Process
Action activity.
If these traces do not provide you with the root cause of the error, you can utilize the graph by
double-clicking the selected activity on the left panel (here Process action). The graph with
related activities is then displayed. You can then expand related activities (by clicking the +
signs) to find the first emitted trace in red or yellow in a related activity. Keep expanding the
activities that happened just before the red or yellow trace of interest, following transfers to
related activities or message flows across endpoints, until you track the root cause of the
problem.
Resource Links for 70-513 WCF Certification Exam
418
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

If ServiceModel ActivityTracing is off but ServiceModel tracing is on, you can see
ServiceModel traces emitted in the 0000 activity. However, this requires more effort to
understand the correlation of these traces.
If Message Logging is enabled, you can use the Message Tab to see which message is impacted
by the error. By double-clicking a message in red or yellow, you can see the graph view of the
related activities. These activities are the ones most closely related to the request where an error
happened.
Resource Links for 70-513 WCF Certification Exam
419
http://msdn.microsoft.com/en-us/library/ms123401.aspx
http://www.jamesjfoster.com/blog/2010/resource-links-for-70-513-wcf-certification-exam/

Das könnte Ihnen auch gefallen