Search content within the blog

Tuesday, August 10, 2010

Implementing transactions in WCF part - II

Flowing Transactions Across Operations
In part - I we saw how transactions can be implemented if the scope of the call is within the same service. However if a call requires that a transaction is completed only if calls to two different services succeeds requires a little extra config and code changes which are explained below.

When working with distributed systems, transactions sometimes must span service boundaries. For instance, if one service managed customer information and another service managed orders, and a user wanted to place an order and ship the product to a new address, the system would need to invoke operations on each service. If the transaction completed, the user would expect that both systems were properly updated.
If infrastructure supports an atomic transactional protocol, the services can be composed into an aggregate transaction as just described. WS-AT (Web Service Atomic Transactions) provides the infrastructure for sharing information among participating services to implement the two-phase commit semantics necessary for ACID transactions. In WCF, flowing transactional information across service boundaries is referred to as transaction flow.To flow transactional semantics across service boundaries, the following five steps must be taken:

(ServiceContract)SessionMode.Required.
Service contracts must require sessions because this is how information will be shared
between the coordinator (typically the client) and the participating services.

(Operation Behavior)TransactionScopeRequired = true.
Operation behavior must require a transaction scope. This will create a
new transaction if one is not already present.

(Operation Behavior)TransactionFlowOption.Allowed
Operation contracts must allow transaction information to flow in the header of messages.

(Binding Definition)TransactionFlow = true.
The binding must enable transaction flow so that the channel can put transaction information into the SOAP header. Also note that the binding must support
sessions because wsHttpBinding does and basicHttpBinding does not.

(client)TransactionScope.
The party that initiates the transaction,
typically the client, must use a transaction scope when calling the
service operations. It must also call TransactionScope.close()to commit the changes.

Implementing transactions in WCF - Part I

Transactional Operations Within a Service
Transactional service operations succeed or fail as a unit. They are initiated
by one party, which assumes that the result will be consistent, whether the
operation succeeds or fails.Figure below depicts pseudo code of this behavior.



The client opens a connection to the service and calls its transfer method. Transfer executes a debit, a credit, and then marks the transaction complete. The client is uninvolved in the transactional semantics.

To implement this behavior in WCF, the service operation must be marked as transactional using the [OperationBehavior(TransactionScoperequired=true)]attribute. This directs WCF to create a new transaction and enlist the execution thread on that transaction before dispatching control to the method. If the operation fails before it is complete, all partial updates to transactional resources within that transaction are rolled back.

if TransactionScoperequired=false is specified, which is the default,the operation executes without a transaction. In that case, the operation will not support ACID properties. If the operation updates one table and then fails updating a second table, updates in the first table will be persisted and the ACID property is violated.

You can indicate that an operation is complete either implicitly or explicitly.
By using the [OperationBehavior(TransactionScoperequired=true)] behavior, the operation is implicitly considered complete if it doesn’t throw an error. If it throws an error, it is considered incomplete and partial updates to transactional resources will be rolled back. Alternatively, you can use the [OperationBehavior(TransactionScoperequired=false)]behavior and then explicitly call
OperationContext.Current.SettransactionComplete() before returning from the method. If you use the explicit method, you also need to use a session-based binding element in the communication channel, and you need to support sessions in the service
contract with [ServiceContract(SessionMode=SessionMode.Allowed)].

Note: The above setting implement Atomic transactions on the calls that are spanning within the same service. If they are calls that span between multiple services within a transaction we need to follow some additional steps. Read "Flowing Transactions Across Operations" to understand it.

Friday, August 6, 2010

Choosing a Message Encoder

This topic discusses criteria for choosing among the message encoders that are included in Windows Communication Foundation (WCF): binary, text, and Message Transmission Optimization Mechanism (MTOM).

In WCF, you specify how to transfer data across a network between endpoints by means of a binding, which is made up of a sequence of binding elements. A message encoder is represented by a message encoding binding element in the binding stack. A binding includes optional protocol binding elements, such as a security binding element or reliable messaging binding element, a required message encoding binding element, and a required transport binding element.

The message encoding binding element sits below the optional protocol binding elements and above the required transport binding element. On the outgoing side, a message encoder serializes the outgoing Message and passes it to the transport. On the incoming side, a message encoder receives the serialized form of a Message from the transport and passes it to the higher protocol layer, if present, or to the application, if not.

When connecting to a pre-existing client or server, you may not have a choice about using a particular message encoding since you need to encode your messages in a way that the other side is expecting. However, if you are writing an WCF service, you can expose your service through multiple endpoints, each using a different message encoding. This allows clients to choose the best encoding for talking to your service over the endpoint that is best for them, as well as giving your clients the flexibility to choose the encoding that is best for them. Using multiple endpoints also allows you to combine the advantages of different message encodings with other binding elements.

System-Provided Encoders
WCF includes three message encoders, which are represented by the following three classes:

* TextMessageEncodingBindingElement, the text message encoder, supports both plain XML encoding and SOAP encoding. The plain XML encoding mode of the text message encoder is called "plain old XML" (POX) to distinguish it from text-based SOAP encoding. To enable POX, set the MessageVersion property to None. Use the text message encoder to interoperate with non-WCF endpoints.

* BinaryMessageEncodingBindingElement, the binary message encoder, uses a compact binary format and is optimized for WCF to WCF communication, and hence is not interoperable. This is also the most performant encoder of all the encoders WCF provides.

* MTOMMessageEncodingBindingElement, the binding element, specifies the character encoding and message versioning for messages using MTOM encoding. MTOM is an efficient technology for transmitting binary data in WCF messages. The MTOM encoder attempts to create a balance between efficiency and interoperability. The MTOM encoding transmits most XML in textual form, but optimizes large blocks of binary data by transmitting them as-is, without conversion to text. In terms of efficiency, among the encoders WCF provides, MTOM is in-between text (the slowest) and binary (the fastest).

How to Choose a Message Encoder
The following table describes common factors used to choose a message encoder. Prioritize the factors that are important for your application, and then choose the message encoders that work best with these factors. Be sure to consider any additional factors not listed in this table and any custom message encoders that may be required in your application.

Comparision between message and transport security.

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.


Message-level security has the following advantages:

* 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

Message security has the following disadvantages:

* Performance

* Cannot use message streaming.

* Requires implementation of XML-level security mechanisms and support for WS-Security specification. This might affect the interoperability.

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:

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.

ACID properties

The ACID Properties are explained below,

Atomic: All updates within the transaction are successful, or they’re all rolled back. No partial updates are allowed. For instance, in a bank transfer, if the debit succeeds but the credit fails, the debit is rolled back so money isn’t created or lost.

Consistent : After the operation, all data is valid according to the business rules. For instance, in a bank transfer, the To and From accounts must be valid accounts or the transaction will abort.

Isolated :While the operation is executing, no partial results are visible outside the transactions. For instance, as a bank transfer is being executed, other users will not see the balances part way through the
transfer.

Durable : After the transaction is committed, the data must be persisted in a way that can survive system failures.

Thursday, August 5, 2010

Use of ignoreExtensionDataObject in WCF

In wcf we can chnage the existing datacontarcts and yet maintain compatability with old clients with the help of extensiondata object genereated
in the proxy.Below is an example that describes it and also explains the use of dataContarctSeralizer ignoreExtensionDataObject,

In wcf we can change the existing data contratcs as per new needs . The chnages can be classified as breaking chnages and
non-breaking chnages.

Nonbreaking Changes

Two types of changes will not break compatibility with existing clients:
• Adding new nonrequired data members
• Removing existing nonrequired data members

Breaking Changes
Change the name or namespace of a data contract.
• Rename an existing data member that was previously required.
• Add a new data member with a name that has been used previously.
• Change the data type of an existing data member.
• Add new members with isrequired = true Datamemberattribute
• Remove existing members with isrequired = true on Datamemberattribute.

Below we have two data contract definitions: The first is defined in a
V1 service, the second in the V2 version of that service. Notice that between
V1 and V2, the data member currency is removed and dailyvolume is
added. This change is nonbreaking.

[Datacontarct(Namespace = "http://stockservice")]
public class stockservice
{
[datamember] public double currentprice
[datamember] public Datetime currentime
[datamember] public string currency
}

[Datacontarct(Namespace = "http://stockservice")]
public class stockservice
{
[datamember] public double currentprice
[datamember] public Datetime currentime
[datamember] public string DailyVolume
}

For existing clients to properly pass around data after new members are added, the original data contract must support extensibility.
That is, the original contract must support serialization of unknown future data. This enables round tripping, where a client can
pass V2 data to a V1 service and have the V1 service return V1 data back to the client with the V2 elements still intact. WCF
implements extensibility by default in the proxy code generated by svcutil.exe. If you do not want to support this capability, it can be disabled
by specifying in the ServiceBehavior section of the service configuration file.

Wednesday, August 4, 2010

WsDualHttpBinding in WCF

Below is the complete code both the server and the client.

Server code
using System;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples
{
// Define a duplex service contract.
// A duplex contract consists of two interfaces.
// The primary interface is used to send messages from client to service.
// The callback interface is used to send messages from service back to client.
// ICalculatorDuplex allows one to perform multiple operations on a running result.
// The result is sent back after each operation on the ICalculatorCallback interface.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required,
CallbackContract=typeof(ICalculatorDuplexCallback))]
public interface ICalculatorDuplex
{
[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);
}

// The callback interface is used to send messages from service back to client.
// The Result operation will return the current result after each operation.
// The Equation opertion will return the complete equation after Clear() is called.
public interface ICalculatorDuplexCallback
{
[OperationContract(IsOneWay = true)]
void Result(double result);
[OperationContract(IsOneWay = true)]
void Equation(string eqn);
}

// Service class which implements a duplex service contract.
// Use an InstanceContextMode of PerSession to store the result
// An instance of the service will be bound to each duplex session
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class CalculatorService : ICalculatorDuplex
{
double result;
string equation;
ICalculatorDuplexCallback callback = null;

public CalculatorService()
{
result = 0.0D;
equation = result.ToString();
callback = OperationContext.Current.GetCallbackChannel();
}

public void Clear()
{
callback.Equation(equation + " = " + result.ToString());
result = 0.0D;
equation = result.ToString();
}

public void AddTo(double n)
{
result += n;
equation += " + " + n.ToString();
callback.Result(result);
}

public void SubtractFrom(double n)
{
result -= n;
equation += " - " + n.ToString();
callback.Result(result);
}

public void MultiplyBy(double n)
{
result *= n;
equation += " * " + n.ToString();
callback.Result(result);
}

public void DivideBy(double n)
{
result /= n;
equation += " / " + n.ToString();
callback.Result(result);
}

}

}
Server code - web.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service
name="Microsoft.ServiceModel.Samples.CalculatorService"
behaviorConfiguration="CalculatorServiceBehavior">
<!-- this endpoint is exposed at the base address provided by host: http://localhost/servicemodelsamples/service.svc -->
<endpoint address=""
binding="wsDualHttpBinding"
contract="Microsoft.ServiceModel.Samples.ICalculatorDuplex" />
<!-- the mex endpoint is exposed at http://localhost/servicemodelsamples/service.svc/mex -->
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>

<!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>

</system.serviceModel>

</configuration>

Client code
using System;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples
{
// The service contract is defined in generatedClient.cs, generated from the service by the svcutil tool.

// Define class which implements callback interface of duplex contract
public class CallbackHandler : ICalculatorDuplexCallback
{
public void Result(double result)
{
Console.WriteLine("Result({0})", result);
}

public void Equation(string eqn)
{
Console.WriteLine("Equation({0})", eqn);
}

}

class Client
{
static void Main()
{
// Construct InstanceContext to handle messages on callback interface
InstanceContext instanceContext = new InstanceContext(new CallbackHandler());

// Create a client with given client endpoint configuration
CalculatorDuplexClient client = new CalculatorDuplexClient(instanceContext);

Console.WriteLine("Press to terminate client once the output is displayed.");
Console.WriteLine();

// Call the AddTo service operation.
double value = 100.00D;
client.AddTo(value);

// Call the SubtractFrom service operation.
value = 50.00D;
client.SubtractFrom(value);

// Call the MultiplyBy service operation.
value = 17.65D;
client.MultiplyBy(value);

// Call the DivideBy service operation.
value = 2.00D;
client.DivideBy(value);

// Complete equation
client.Clear();

Console.ReadLine();

//Closing the client gracefully closes the connection and cleans up resources
client.Close();
}

}
}

Client code (app.config)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>

<client>
<endpoint address="http://localhost/servicemodelsamples/service.svc"
binding="wsDualHttpBinding"
bindingConfiguration="Binding1"
contract="Microsoft.ServiceModel.Samples.ICalculatorDuplex" />
</client>

<bindings>
<!-- configure a WSDualHttpBinding that supports duplex communication -->
<wsDualHttpBinding>
<binding name="Binding1"
clientBaseAddress="http://localhost:8000/myClient/"
useDefaultWebProxy="true"
bypassProxyOnLocal="false">
</binding>
</wsDualHttpBinding>
</bindings>

</system.serviceModel>

</configuration>

Tuesday, August 3, 2010

Adding a mex endpint and httgGetEnabled in wcf service

The Metadata Exchange Endpoint (MEX) is a special endpoint in WCF that exposes metadata used to describe a service. In previous releases of WCF, the MEX was implicitly added to all services. However, due to security reasons, it is no longer exposed by default as of RC1. Without the MEX, you will not be able to use svcutil.exe to automatically generate a proxy class. Fortunately, it is a simply process to enable the MEX for your service.

The MEX can be exposed programatically or via configuration (just like any other endpoint).

To programatically expose the MEX:

using System.ServiceModel;
using System.ServiceModel.Description;

ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior);

host.AddServiceEndpoint(
typeof(IMetadataExchange),
MetadataExchangeBindings.CreateMexHttpBinding(),
"http://localhost/MyService/mex/");

Please note that ServiceMetadataBehavior, IMetadataExchange, and MetadataExchangeBindings reside within the System.ServiceModel.Description namespace. This threw me off when I was first searching for them.

To expose the MEX via configuration:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="MyService"
behaviorConfiguration="DefaultBehavior">
<endpoint address=http://localhost/MyService
binding="basicHttpBinding"
contract="IMyService" />
<endpoint address="http://localhost/MyService/mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

Depending upon your binding, the corresponding MEX binding will vary. There is support for HTTP, TCP, and Named Pipes. If you are adding the MEX programatically, there are corresponding methods in the MetadataExchangeBindings object. If you adding the MEX via configuration, the equivalent binding is fairly obvious to figure out. Essentially, use mex?Binding and replace the ? with whatever you are using.

It should be noted that you are not required to enable HttpGet. SvcUtil will still be able to access the MEX without it. However, it is useful if you want to view the WSDL from a browser by going to the address of the service. You cannot do so without enabling the HttpGet.