Tuesday, 25 October 2011

Learn WPF in one Week

I started to build a one week training course to learn WPF. Starting with the basics and going through the important concepts of the framework up to more complex topics. I hope you like it.

Day 1 - Getting started

Day 2 - Concepts of WPF

Day 3 - Layout and Controls

Day 4 - DataBinding and UI Architecture

Day 5 - Templates and Styles

Some of the articles are not yet finished. The content for the subsequent days will follow soon... :-)

How to create a simple WPF application

In Visual Studio 2008

Open Visual Studio 2008 and choose "File", "New", "Project..." in the main menu. Choose "WPF Application" as project type.
Choose a folder for your project and give it a name. Then press "OK"
Visual Studio creates the project and automatically adds some files to the solution. A Window1.xaml and an App.xaml. The structure looks quite similar to WinForms, except that the Window1.designer.cs file is no longer code but it's now declared in XAML as Window1.xaml
Open the Window1.xaml file in the WPF designer and drag a Button and a TextBox from the toolbox to the Window
Select the Button and switch to the event view in the properties window (click on the little yellow lightning icon). Doubleclick on the "Click" event to create a method in the codebehind that is called, when the user clicks on the button.
Note: If you do not find a yellow lightning icon, you need to install the Service Pack 1 for VisualStudio on your machine. Alternatively you can doubleclick on the button in the designer to achieve the same result.
Visual Studio automatically creates a method in the code-behind file that gets called when the button is clicked.
 
private void button1_Click(object sender, RoutedEventArgs e)
{
    textBox1.Text = "Hello WPF!";
}
 
 
The textbox has automatically become assigned the name textBox1 by the WPF designer. Set text Text to "Hello WPF!" when the button gets clicked and we are done! Start the application by hit [F5] on your keyboard.
Isn't this cool!

Videos about WPF

Books about WPF

Brand New!

WPF 4 - Unleashed

In my opinion one of the best books about WPF - now updated to version 4.0. It's printed fully in color, so all code samples have syntax highlighting. It includes all the good explanations and samples of version 3 including new chapters about multitouch, XAML 2009, VSM, improved text rendering, windows 7 shell integration and more.
Autor: Adam Nathan
ISBN: 978-0672331190
Published: June 2010

Find it at Amazon

WPF Control Development Unleashed

In this book, two leading Windows Presentation Foundation experts give developers everything they need to build next-generation WPF applications--software that is more robust, usable, and compelling. Drawing on their close ties with Microsoft's WPF development team, Pavan Podila and Kevin Hoffman give you a clear, robust, and practical understanding of WPF, its underpinnings, its overall architecture, and its design philosophy.
Autor: Pavan Podila, Kevin Hoffman
ISBN: 978-0672330339
Published: September 2009

Find it at Amazon

Windows Presentation Foundation - Unleashed     (My favorite!)

In my opinion one of the best book about WPF. It covers all important themes including 3D programming. All code samples have syntax highlighting. Digging deeper sections with additional informations for advanced programmers.
Autor: Adam Nathan
ISBN: 978-0672328916
Published: January 2007

Find it at Amazon

Application = Code + Markup

"Get the definitive guide to the Windows Presentation Foundation (WPF), the new client programming interface for the Microsoft .NET Framework 3.0 and Windows Vista. Award-winning author Charles Petzold teaches you how to combine C# code and the Extensible Application Markup Language (XAML) to develop applications for the WPF.". I cannot unterstand how anyone can write a book about a UI technology without a single illustration. If you prefer gray text to colorful images, it might be the book for you.
Autor: Charles Petzold
ISBN: 978-0735619579
Published: August 2006

Essential Windows Presentation Foundation

Chris Anderson was one of the chief architects of the next-generation GUI stack, the Windows Presentation Framework (WPF), which is the subject of this book. Chris's insights shine a light from the internals of WPF to those standing at the entrance, guiding you through the concepts that form the foundation of his creation.
Autor: Chris Anderson
ISBN: 978-0321374479
Published: April 2007

Foundations of WPF: An Introduction to Windows Presentation Foundation

Foundations of WPF: An Introduction to Windows Presentation Foundation teaches you everything you need to get started with the technology, and is broken into three parts. The first introduces and contextualizes the WPF technology; the second part dives deeper into the facets of the technology that are of immediate and valuable use in developing applications; the last part offers you the real-world perspective you need to be productive in the community and customer base.
Autor: Laurence Moroney
ISBN: 978-1590597606
Published: November 2006

Pro WPF in C# 2008

This book explains how WPF works from the ground up. It follows on from the author s previous and highly successful books, covering Windows Forms (WPF's predecessor technology) and earlier versions of WPF. It is a one-stop shop in Apress proven Pro style that leaves readers with a deep understanding of the technology and able to take the concepts away and apply them for themselves.
Autor: Matthew McDonald
ISBN: 978-1590599556
Published: Februar 2008

Foundations of WPF: An Introduction to Windows Presentation Foundation

If you want to build applications that take full advantage of Windows Vista's new user interface capabilities, you need to learn Microsoft's Windows Presentation Foundation (WPF). This new edition, fully updated for the official release of .NET 3.0, is designed to get you up to speed on this technology quickly.
Autor: Chris Sells and Ian Griffiths
ISBN: 978-0596510374
Published: September 2007

WPF Development Tools

Microsoft provides two development tools for WPF applications. One is Visual Studio, made for developers and the other is Expression Blend made for designers. While Visual Studio is good in code and XAML editing, it has a rare support for all the graphical stuff like gradients, template editing, animation, etc. This is the point where Expression Blend comes in. Blend covers the graphical part very well but it has (still) rare support for code and XAML editing.
So the conclusion is that you will need both of them.

Microsoft Visual Studio 2010

Visual Studio is the tool for developers to develop WPF applications. It includes a graphical designer for WPF since version 2008. If you're using Visual Studio 2005 you can install an add-on that enables you to develop WPF applications.
Microsoft provides a free Express Edition of Visual Studio that also includes the WPF designer. You can download it from the following URL
Download Microsoft Visual C# 2010 - Express Edition


Microsoft Expression Blend 3 + Sketch Flow

Expression Blend is the tool for designers. It's part of the Expression Studio, a new tool suite from Microsoft especially created for user experience designers. Blend covers all the missing features of the Visual Studio designer like styling, templating, animations, 3D graphics, resources and gradients.
In the latest Version it also includes a powerful prototyping tool called SketchFlow. Expression Blend can open solution files created by visual studio.
Download Microsoft Expression Blend 3


Other useful tools

  • WPF Inspector
  • Snoop (Inspect the Visual Tree of running WPF applications)
  • Mole (Data Visualizer for Visual Studio
  • XAML Power Toys
  • WPF Performance Suite

Introduction to Windows Presentation Foundation

Overview

The Windows Presentation Foundation is Microsofts next generation UI framework to create applications with a rich user experience. It is part of the .NET framework 3.0 and higher.
WPF combines application UIs, 2D graphics, 3D graphics, documents and multimedia into one single framework. Its vector based rendering engine uses hardware acceleration of modern graphic cards. This makes the UI faster, scalable and resolution independent.
The followinig illustration gives you an overview of the main new features of WPF

Separation of Appearance and Behavior

WPF separates the appearance of an user interface from its behavior. The appearance is generally specified in the Extensible Application Markup Language (XAML), the behavior is implemented in a managed programming language like C# or Visual Basic. The two parts are tied together by databinding, events and commands. The separation of appearance and behavior brings the following benefits:
  • Appearance and behaviour are loosely coupled
  • Designers and developers can work on separate models.
  • Graphical design tools can work on simple XML documents instead of parsing code.

Rich composition

Controls in WPF are extremely composable. You can define almost any type of controls as content of another. Although these flexibility sounds horrible to designers, its a very powerful feature if you use it appropriate. Put an image into a button to create an image button, or put a list of videos into a combobox to choose a video file.


 
<Button>
    <StackPanel Orientation="Horizontal">
        <Image Source="speaker.png" Stretch="Uniform"/>
        <TextBlock Text="Play Sound" />
    </StackPanel>
</Button>
 
 

Highly customizable

Because of the strict separation of appearance and behavior you can easily change the look of a control. The concept of styles let you skin controls almost like CSS in HTML. Templates let you replace the entire appearance of a control.
The following example shows an default WPF button and a customized button.

Resolution independence

All measures in WPF are logical units - not pixels. A logical unit is a 1/96 of an inch. If you increase the resolution of your screen, the user interface stays the same size - it just gets crispier. Since WPF builds on a vector based rendering engine it's incredibly easy to build scaleable user interfaces.




Wednesday, 19 October 2011

Introdution to WCF 4.0

This article explains about the new features introduced in WCF 4.0.
.Net framework comes with new features and improved areas of WCF. It was mainly focused on simplifying the developer experience, enabling more communication scenario and providing rich integration with WWF.
The following items specifies the new features of WCF 4.0
Simplified configuration
This new feature shows simplification of WCF configuration section by providing default endpoint, binding and behavior configuration. It is not mandatory to provide endpoint while hosting service. Service will automatically create new endpoint if it does find any endpoint while hosting service. These changes make it possible to host configuration-free services.
Discovery service
There are certain scenario in which endpoint address of the service will be keep on changing. In that kind of scenario, client who consume this service also need to change the endpoint address dynamically to identify the service. This can be achieved using WS-Discovery protocol.
Routing service
This new feature introduces routing service between client and actual business service. This intermediated service Act as broker or gateways to the actual business services and provides features for content based routing, protocol bridging and error handling
REST Service
There are few features helps while developing RESTful service.
  • Automatic help page that describes REST services to consumer
  • Support for declarative HTTP catching
Workflow service
  • Improves development experience
  • Entire service definition can be define in XAML
  • Hosting workflow service can be done from .xamlx file, without using .svc file
  • Introduce new “Context” bindings like BasicHttpContextBinding, WSHttpContextBinding, or NetTcpContextBinding
  • In .Net4.0, WorkflowServiceHost class for hosting workflow services was redesigned and it is available in System.ServiceModel.Activities assembly. In .Net3.5, WorkflowServiceHost class is available in System.WorkflowServices assembly
  • New messaging activities SendReply and ReceiveReply are added in .Net4.0

Custom message header

This article explains about customizing the wcf message flowing between service and client.
There are certain scenario in which you to pass some information from client to service, but not as parameter in operation contracts. Example, logging system at the service we need to log user or machine information, which made request to the service. In this kind of scenario we should not pass user or machine information as parameter in operation contract. Instead we can pass the information through message flowing between client and service vice versa. The information we need to send can be appended with message header and it can be received at the server side.
Let as create sample service and client application, in which client will send “User name” information through request message and service will respond with confirmation message.
I have created Math service with Add and Subtract functionality. Client consuming this service will send his user name information as string with requested message. Once request reached the service, it will read the information from the message header and display using console window. When service responding to the client, along with operation result, it will also send confirmation message to client through message header.
Step 1: Create IMathService interface decorated with Service and Operational contract attribute
IMathService.vb
<ServiceContract()> _
Public Interface IMathService
    <OperationContract()> _
    Function Add(ByVal a As Integer, ByVal b As Integer) As Integer
    <OperationContract()> _
    Function Subtract(ByVal a As Integer, ByVal b As Integer) As Integer
End Interface
Step 2:In this class, we have implemented Add and Subtract functionality.
PrintRequestedUserID() method will read the “UserID” message header from incoming message using OperationContext. This User information is displayed in console window.
SendResponseWithMessage() method will send a confirmation message to the client as Message header through Operation context.
MathService.vb
Public Class MathService
    Implements IMathService

    Public Function Add(ByVal a As Integer, ByVal b As Integer) As Integer 
    Implements IMathService.Add
        'This method call will retrive message send from client using MessageHeader
        PrintRequestedUserID()
        'This method call will send message to client using MessageHeader
        SendResponseWithMessage()
        Return a + b

    End Function

    Public Function Subtract(ByVal a As Integer, ByVal b As Integer) As Integer 
    Implements IMathService.Subtract
        'This method call will retrive message send from client using MessageHeader
        PrintRequestedUserID()
        'This method call will send message to client using MessageHeader
        SendResponseWithMessage()
        Return a - b
    End Function

    Private Sub PrintRequestedUserID()
        Dim userID As String = String.Empty
        'Read the message header using "Name" and "NameSpace"
        userID = OperationContext.Current.IncomingMessageHeaders
                                    .GetHeader(Of String)("UserID", "ns")
        Console.WriteLine("Requested user: " + userID)
    End Sub

    Private Sub SendResponseWithMessage()
        'Creating new message header with "Content" value assigned in constructor
        Dim mess As New MessageHeader(Of String)("This is sample message from service")
        'Assigning Name and NameSpace to the message header value at server side
        Dim header As System.ServiceModel.
                    Channels.MessageHeader = mess.GetUntypedHeader("ServiceMessage", "ns")
        'Adding message header with OperationContext 
        'which will be received at the client side
        OperationContext.Current.OutgoingMessageHeaders.Add(header)
    End Sub
End Class
Step 3: Hosting the MathService using console application
MyServiceHost.vb
       Module MyServiceHost

    Sub Main()
        'Hosting the Math service using console application
        Dim host As New ServiceHost(GetType(MyService.MathService))
        host.Open()
        Console.WriteLine("Service is running... Press  to exit.")
        Console.ReadLine()
    End Sub

End Module

Web.Config
      <system.serviceModel>
    <services><service name="MyService.MathService" 
    behaviorConfiguration="MyServiceBehavior">
        <endpoint address ="MathService" binding="basicHttpBinding" 
        contract="MyService.IMathService"/>
        <endpoint  address="mex" binding="mexHttpBinding" 
        contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8090/MyService"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors >
        <behavior name ="MyServiceBehavior">
          <serviceMetadata httpGetEnabled ="true"/>
            <serviceDebug includeExceptionDetailInFaults ="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Step 4: Created console client application which add “UserID” as message header to service using Operation context before calling Add() functionality. Once the response is received from the service, it is trying to read the confirmation message from service using Operation context.
Sub Main()
        'Creating proxy class for service
        Dim proxy As IMathService = Nothing
        proxy = ChannelFactory(Of IMathService).CreateChannel(New BasicHttpBinding(), 
                    New EndpointAddress("http://localhost:8090/MyService/MathService"))

        'Lifetime of OperationContextScope defines the scope for OperationContext.
        Dim scope As OperationContextScope = Nothing
        scope = New OperationContextScope(proxy)
       
        'Creating new message header with "Content" value assigned in constructor
        Dim mess As New MessageHeader(Of String)
                         (System.Security.Principal.WindowsIdentity.GetCurrent().Name)
        'Assigning Name and NameSpace to the message header value at client side
        Dim header As System.ServiceModel.Channels.MessageHeader 
                                    = mess.GetUntypedHeader("UserID", "ns")
        'Adding message header with OperationContext 
        'which will be received at the server side
        OperationContext.Current.OutgoingMessageHeaders.Add(header)

        'Making service call
        Console.WriteLine("Sum of {0},{1}={2}", 1, 2, proxy.Add(1, 2))
        'Displaying confrimation message from service
        Console.WriteLine("Response Message: " + OperationContext.Current.
                    IncomingMessageHeaders.GetHeader(Of String)("ServiceMessage", "ns"))
        Console.ReadLine()
    End Sub

End Module

<ServiceContract()> _
Public Interface IMathService
    Inherits IClientChannel

    <OperationContract()> _
    Function Add(ByVal a As Integer, ByVal b As Integer) As Integer
    <OperationContract()> _
    Function Subtract(ByVal a As Integer, ByVal b As Integer) As Integer
End Interface

Step 5: Run the MyServiceHost
Step 6: Run the MyClientApplication
Below figure shows the message flowing between service and client
Client application output
Console hosted service output screen
Conclusion:
This article explain about customizing the wcf message header

Handling Exception in Silverlight application from WCF

This article explains about handling the exception in Silverlight application from WCF. I have created the sample Silverlight application, which uses the WCF service for process the data. While testing the application I came to know that exception message thrown from WCF cannot be received at the client side(Silverlight application) even after using the FaultException. I was always getting System.ServiceModel.CommunicationException: The remote server returned an error: NotFound.
Imports System.ServiceModel.ConfigurationrviceModel.Configuration
Imports System.ServiceModel.Description
Imports System.ServiceModel.Dispatcher
Imports System.ServiceModel.Channels
Imports System.ServiceModel

    Public Class SilverlightFaultBehavior
        Inherits BehaviorExtensionElement
        Implements IEndpointBehavior


        Public Overrides ReadOnly Property BehaviorType() As System.Type
            Get
                Return GetType(SilverlightFaultBehavior)
            End Get
        End Property

        Protected Overrides Function CreateBehavior() As Object
            Return New SilverlightFaultBehavior
        End Function

        Public Sub AddBindingParameters(ByVal endpoint As ServiceEndpoint,
                                     ByVal bindingParameters As BindingParameterCollection)
                                     Implements IEndpointBehavior.AddBindingParameters

        End Sub

        Public Sub ApplyClientBehavior(ByVal endpoint As ServiceEndpoint, 
                                       ByVal clientRuntime As ClientRuntime) 
                                       Implements IEndpointBehavior.ApplyClientBehavior

        End Sub

        Public Sub ApplyDispatchBehavior(ByVal endpoint As ServiceEndpoint, 
                          ByVal endpointDispatcher As EndpointDispatcher) 
                          Implements IEndpointBehavior.ApplyDispatchBehavior
            Dim inspector As New SilverlightFaultMessageInspector()
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(inspector)
        End Sub

        Public Sub Validate(ByVal endpoint As ServiceEndpoint)
                                         Implements IEndpointBehavior.Validate

        End Sub

        Public Class SilverlightFaultMessageInspector
            Implements IDispatchMessageInspector

            Public Function AfterReceiveRequest(ByRef request As Message, 
                                     ByVal channel As IClientChannel,
                                     ByVal instanceContext As InstanceContext) As Object 
                                     Implements IDispatchMessageInspector.AfterReceiveRequest
                ' Do nothing to the incoming message. 
                Return Nothing
            End Function

            Public Sub BeforeSendReply(ByRef reply As System.ServiceModel.Channels.Message,
                                       ByVal correlationState As Object) 
                                       Implements IDispatchMessageInspector.BeforeSendReply
                If reply.IsFault Then
                    Dim [property] As New HttpResponseMessageProperty()

                    ' Here the response code is changed to 200. 
                    [property].StatusCode = System.Net.HttpStatusCode.OK
                    reply.Properties(HttpResponseMessageProperty.Name) = [property]
                End If
            End Sub
        End Class

    End Class


Note: Highlighted code shows the conversion for 500 serices to 200 series error code.
Step 2: Build the project
Step 3: Create a new WCF service with Interface and implementation class as follows
Interface
<ServiceContract()> _
Public Interface IService
    <OperationContract()> _
    Function Add(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
    <OperationContract()> _
    Function Subtract(ByVal num1 As Integer, ByVal num2 As Integer) As Integer

   
End Interface

Implementation
Public Class Service
    Implements IService

    Public Sub New()
    End Sub

    Public Function Add(ByVal num1 As Integer, ByVal num2 As Integer)
                                         As Integer Implements IService.Add
        Throw New FaultException("Error thrown by user for Add operation")
        'Return num1 + num2
    End Function

    Public Function Subtract(ByVal num1 As Integer, 
                            ByVal num2 As Integer) As Integer Implements IService.Subtract
        Return num1 - num2
    End Function
End Class


< Add the Silverlight_WCF_FaultBehavior project dll as reference to WCF Service
Step 5:
Step 5: In WCF we can extend the binding and behavior by using <extention> tag. In our case also we are extending the custom endpoint behavior as shown below. In the <behaviorExtensions> tag we need specify the fully qualified name of the cutom behaviour assembly.
Modify the Web.config file as shown bellow
<system.serviceModel>
    <services>
      <service name="Service" behaviorConfiguration="ServiceBehavior">
        <!-- Service Endpoints -->
        <endpoint address="" binding="basicHttpBinding" contract="IService"
         behaviorConfiguration="SilverlightFaultBehavior">
          <!-- 
              Upon deployment, the following identity element should be removed or replaced 
              to reflect the identity under which the deployed service runs.  If removed, 
              WCF will infer an appropriate identity automatically.-->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <!-- To avoid disclosing metadata information, set the value below to false and 
          remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value 
          below to true.  Set to false before deployment to avoid disclosing exception 
          information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="SilverlightFaultBehavior">
          <silverlightFaults/>
        </behavior>
      </endpointBehaviors>
    </behaviorss=“BlueCode”>>
    <extensions>
      <behaviorExtensions>
        <add name="silverlightFaults" 
        type="Silverlight_WCF_FaultBehavior.SilverlightFaultBehavior, 
        Silverlight_WCF_FaultBehavior, Version=1.0.0.0, Culture=neutral, 
        PublicKeyToken=null"/>
      </behaviorExtensions>
    </extensionss=“BlueCode”>>
  </system.serviceModel>
Step 6: Create the any sample silverlight application as “Silverlight_WCF_Exception” and add this WCF service as Service Reference.
url: http://localhost/MathService/Service.svc
Step 7: Add a button to the MainPage.xaml and call the WCF method as shown below
Private Sub Button_Click(ByVal sender As System.Object,
                             ByVal e As System.Windows.RoutedEventArgs)
        Dim proxy As New ServiceProxy.ServiceClient
        AddHandler proxy.AddCompleted, AddressOf AddOperationCompleted
        proxy.AddAsync(5, 6)
    End Sub

    Private Sub AddOperationCompleted(ByVal sender As Object, 
                                    ByVal e As ServiceProxy.AddCompletedEventArgs)
        If e.Error IsNot Nothing Then
            MessageBox.Show(e.Error.Message)
        Else
            MessageBox.Show(e.Result)
        End If
    End Sub

Step 8: Output will look like this
Later I came to know that WCF throws the HTTP 500 series Fault message but Silverlight can handle only 200 series. So we need to convert the 500 series to 200 error message for Silverlight. Here is the sample application for exception handling between WCF and Silverlight.
Step 1: We can customize the Endpoint behavior of the WCF service by inheriting the Beha and implementing the IEndpointBehavior. Actual code for converting the 500 error serice to 200 serivce in BeforeSendReply method.
Create a ClassLibrary project and name it as “Silverlight_WCF_FaultBehavior” and name the class as “SilverlightFaultBehavior”. Copy and paste the follwing code inside the SilverlightFaultBehavior class.

Transaction Protocols

As a developer we no need to concern about transaction protocols and transaction manager used by WCF. WCF itself will take care of what kind of transaction protocols should be used for different situation. Basically there are three different kinds of transaction protocols used by WCF.

Transaction Propagation

In WCF, transaction can be propagated across service boundary. This enables service to participate in a client transaction and it includes multiple services in same transaction, Client itself will act as service or client.
We can specify whether or not client transaction is propagated to service by changing Binding and operational contract configuration
<bindings>
      <netTcpBinding>
        <binding transactionFlow="true"></binding>
      </netTcpBinding>
    </bindings>
Even after enabling transaction flow does not mean that the service wants to use the client’s transaction in every operation. We need to specify the “TransactionFlowAttribute” in operational contract to enable transaction flow.
[ServiceContract]
public interface IService
{

    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Allowed)]
    int Add(int a, int b);

    [OperationContract]
    int Subtract(int a, int b);
}

Note: TransactionFlow can be enabled only at the operation level not at the service level.
TransactionFlowOption Binding configuration
NotAllowed transactionFlow="true"
or
transactionFlow
="false"
Client cannot propagate its transaction to service even client has transaction
Allowed transactionFlow="true" Service will allow to flow client transaction.
It is not necessary that service to use client transaction.
Allowed transactionFlow="false" If service disallows at binding level, client also should disable at binding level else error will be occurred.
Mandatory transactionFlow="true" Both Service and client must use transaction aware binding
Mandatory transactionFlow="false" InvalidOperationException will be throw when serice binding disables at binding level.
FaultException will be thrown when client disable at its binding level.

Two-phase committed protocol

Consider the scenario where I am having single client which use single service for communication and interacting with single database. In which service starts and manage the transaction, now it will be easy for the service to manage the transaction.
Consider for example client calling multiple service or service itself calling another service, this type of system are called as Distributed Service-oriented application. Now the questions arise that which service will begin the transaction? Which service will take responsibility of committing the transaction? How would one service know what the rest of the service feels about the transaction? Service could also be deployed in different machine and site. Any network failure or machine crash also increases the complexity for managing the transaction.
In order to overcome these situations, WCF come up with distributed transaction using two way committed protocol and dedicated transaction manager.
Transaction Manager is the third party for the service that will manage the transaction using two phase committed protocol.
Let us see how Transaction manager will manage the transaction using two-phase committed protocols.

Transaction

A transaction is a collection or group of one or more units of operation executed as a whole. It provides way to logically group single piece of work and execute them as a single unit. In addition, WCF allows client applications to create transactions and to propagate transactions across service boundaries.

Recovery Challenge

Let us discuss more on challenge we will phased and how to recover from it.
  1. Consider a system maintained in consistent state, when application fail to perform particular operation, you should recover from it and place the system in the consistent state.
  2. While doing singe operation, there will be multiple atomic sub operation will happen. These operations might success or fail. We are not considering about sub operation which are failed. We mainly consider about the success operation. Because we have to recover all these state to its previous consistence state.
  3. Productivity penalty has to be payee for all effort required for handcrafting the recovery logic
  4. Performance will be decreased because you need to execute huge amount of code.

Solution

Best way to maintain system consistence and handling error-recovery challenge is to use transactions. Below figure gives idea about transaction.
  • Committed transaction: Transaction that execute successfully and transfer the system from consistence state A to B.
  • Aborted transaction: Transaction encounters an error and rollback to Consistence State A from intermediate state.
  • In-doubt transaction: Transactions fail to either in commit or abort.

Transaction Resources

Transactional programming requires working with a resource that is capable of participating in a transaction, and being able to commit or roll back the changes made during the transaction. Such resources have been around in one form or another for decades. Traditionally, you had to inform a resource that you would like to perform transactional work against it. This act is called enlisting. Some resources support auto-enlisting.

Transaction Properties

Transaction can be said as pure and successful only if meets four characteristics.
  • Atomic - When transaction completes, all the individual changes made to the resource while process must be made as to they were all one atomic, indivisible operation.
  • Consistent - transaction must leave the system in consistent state.
  • Isolated - Resources participating in the transaction should be locked and it should not be access by other third party.
  • Durable - Durable transactions must survive failures.

Streaming

Client and Service exchange message using Streaming transfer mode, receiver can start processing the message before it is completely delivered. Streamed transfers can improve the scalability of a service by eliminating the requirement for large memory buffers. If you want to transfer large message, streaming is the best method.

Supported Bindings

  • BasicHttpBinding
  • NetTcpBinding
  • NetNamedPipeBinding

Restrictions

There are some restriction, when streaming is enabled in WCF
  • Digital signatures for the message body cannot be performed
  • Encryption depends on digital signatures to verify that the data has been reconstructed correctly.
  • Reliable sessions must buffer sent messages on the client for redelivery if a message gets lost in transfer and must hold messages on the service before handing them to the service implementation to preserve message order in case messages are received out-of-sequence.
  • Streaming is not available with the Message Queuing (MSMQ) transport
  • Streaming is also not available when using the Peer Channel transport

I/O Streams

WCF uses .Net stream class for Streaming the message. Stream in base class for streaming, all subclasses like FileStream,MemoryStream, NetworkStream are derived from it. Stream the data, you need to do is, to return or receive a Stream as an operation parameter.
[ServiceContract]
public interface IMyService
{
    [OperationContract]
    void SaveStreamData(Stream emp);

    [OperationContract]
    Stream GetStreamData();

}
Note:
  1. Stream and it's subclass can be used for streaming, but it should be serializable
  2. Stream and MemoryStream are serializable and it will support streaming
  3. FileStream is non serializable, and it will not support streaming

Streaming and Binding

Only the TCP, IPC, and basic HTTP bindings support streaming. With all of these bindings streaming is disabled by default. TransferMode property should be set according to the desired streaming mode in the bindings.
public enum TransferMode
{
   Buffered, //Default
   Streamed,
   StreamedRequest,
   StreamedResponse
}
public class BasicHttpBinding : Binding,...
{
   public TransferMode TransferMode
   {get;set;}
   //More members
}
  • StreamedRequest - Send and accept requests in streaming mode, and accept and return responses in buffered mode
  • StreamResponse - Send and accept requests in buffered mode, and accept and return responses in streamed mode
  • Streamed - Send and receive requests and responses in streamed mode in both directions
  • Buffered -Send and receive requests and responses in Buffered mode in both directions

Streaming and Transport

The main aim of the Streaming transfer mode is to transfer large size data, but default message size is 64K. So you can increase the message size using maxReceivedMessageSize attribute in the binding element as shown below.
<system.serviceModel>
    <bindings >
      <netTcpBinding>
        <binding name="MyService.netTcpBinding"
         transferMode="Buffered" maxReceivedMessageSize="1024000">
        </binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>

WCF Transfer mode

In our normal day today life, we need to transfer data from one location to other location. If data transfer is taking place through WCF service, message size will play major role in performance of the data transfer. Based on the size and other condition of the data transfer, WCF supports two modes for transferring messages

Buffer transfer

When the client and the service exchange messages, these messages are buffered on the receiving end and delivered only once the entire message has been received. This is true whether it is the client sending a message to the service or the service returning a message to the client. As a result, when the client calls the service, the service is invoked only after the client's message has been received in its entirety; likewise, the client is unblocked only once the returned message with the results of the invocation has been received in its entirety.

Stream transfer

When client and Service exchange message using Streaming transfer mode, receiver can start processing the message before it is completely delivered. Streamed transfers can improve the scalability of a service by eliminating the requirement for large memory buffers. If you want to transfer large message, streaming is the best method.

StreamRequest

In this mode of configuration, message send from client to service will be streamed

StreamRespone

In this mode of configuration, message send from service to client will be streamed.

Configuration

<system.serviceModel>
    <services >
      <service behaviorConfiguration="ServiceBehavior"  name="MyService">
        <endpoint address="" binding="netTcpBinding"
         bindingConfiguration="MyService.netTcpBinding" contract="IMyService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" 
        contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true "/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings >
      <netTcpBinding>
        <binding name="MyService.netTcpBinding" 
        transferMode="Buffered" closeTimeout ="0:01:00" openTimeout="0:01:00"></binding>
      </netTcpBinding>
    </bindings>
  </system.serviceModel>

Differences between Buffered and Streamed Transfers

Buffered Streamed
Target can process the message once it is completely received. Target can start processing the data when it is partially received
Performance will be good when message size is small Performance will be good when message size is larger(more than 64K)
Native channel shape is IDuplexSessionChannel Native channels are IRequestChannel and IReplyChannel

Saturday, 15 October 2011

Events

Events allow the client or clients to be notified about something that has occurred on the service side. An event may result from a direct client call, or it may be the result of something the service monitors. The service firing the event is called the publisher, and the client receiving the event is called the subscriber.
  • Publisher will not care about order of invocation of subscriber. Subscriber can be executed in any manner.
  • Implementation of subscriber side should be short duration. Let us consider the scenario in which you what to publish large volume of event. Publisher will be blocked, when subscriber is queued on previous subscription of the event. These make publishers to put in wait state. It may lead Publisher event not to reach other subscriber.
  • Large number of subscribers to the event makes the accumulated processing time of each subscriber could exceed the publisher's timeout
  • Managing the list of subscribers and their preferences is a completely service-side implementation. It will not affect the client; publisher can even use .Net delegates to manage the list of subscribers.
  • Event should always one-Way operation and it should not return any value

Definition

    public interface IMyEvents
    {
        [OperationContract(IsOneWay = true)]
        void Event1();
    }
Let us understand more on Event operation by creating sample service
Step 1 : Create ClassLibrary project in the Visual Studio 2008 and name it as WCFEventService as shown below.
Step 2: Add reference System.ServiceModel to the project
Create the Event operation at the service and set IsOnwWay property to true. This operation should not return any value. Since service has to communicate to the client, we need to use CallbackContract for duplex communication. Here we are using one operation to subscribe the event and another for firing the event.
public interface IMyEvents
    {
        [OperationContract(IsOneWay = true)]
        void Event1();
    }

   [ServiceContract(CallbackContract = typeof(IMyEvents))]
   public interface IMyContract
   {
       [OperationContract]
       void DoSomethingAndFireEvent();

       [OperationContract]
       void SubscribeEvent();

   }
Step 3: Implementation of the Service Contract is shown below.
In the Subscription operation, I am using Operationcontext to get the reference to the client instance and Subscription method is added as event handler to the service event. DoSomethingAndFireEvent operation will fire the event as shown.
MyPublisher.cs
   [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
   public  class MyPublisher : IMyContract
    {
        static Action m_Event1 = delegate { };

        public void SubscribeEvent()
        {
            IMyEvents subscriber = OperationContext.Current.GetCallbackChannel();
            m_Event1 += subscriber.Event1;
        }

        public static void FireEvent()
        {
            m_Event1();
        }

        public void DoSomethingAndFireEvent()
        {
            MyPublisher.FireEvent();           
        }
    }
Step 4: Create the Console application using Visual Studio 2008 and name it as WcfEventServiceHost. This application will be used to self-host the service.
Step 5: Add System.ServiceModel and WcfEventService as reference to the project.
static void Main(string[] args)
        {
            Uri httpUrl = new Uri("http://localhost:8090/MyPublisher/");
            ServiceHost host = new ServiceHost(typeof(WcfEventService.MyPublisher), httpUrl);
            host.Open();
            Console.WriteLine("Service is Hosted at {0}", DateTime.Now.ToString());
            Console.WriteLine("Host is running...Press  key to stop the service.");
            Console.ReadLine();
            host.Close();
        }
  
Step 6: Use Duplex binding to support Callback operation.
Web.Config
<system.serviceModel>
    <services >
      <service behaviorConfiguration="ServiceBehavior"  
      name="WcfEventService.MyPublisher">
        <endpoint address="http://localhost:8090/MyPublisher" 
        binding="wsDualHttpBinding" contract="WcfEventService.IMyContract">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding"
         contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true "/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
Step7: Run the host application as shown below.
Step 8: Create the console application using visual studio and name it as WcfEventServiceClient as shown below. This application will act a client which is used to subscribe the event from service.
Step 9: Create the proxy class as shown below. Use DuplexClientBase to create the proxy, because it will support bidirectional communication. Create the contractor which will accept InstanceContext as parameter.
EventServiceClient.cs
 class EventServiceClient:DuplexClientBase<IMyContract>,IMyContract 
    {
        public EventServiceClient(InstanceContext eventCntx)
            : base(eventCntx)
        {
            
        }

        public void  DoSomethingAndFireEvent()
        {
            base.Channel.DoSomethingAndFireEvent();
        }

        public void SubscribeEvent()
        {
            base.Channel.SubscribeEvent();
        }
      
    }
Step 10: Implementation of IMyEvents at client side is shown below. This method will be called when service publish the event.
class MySubscriber : IMyEvents
    {
       public void Event1()
        {
            Console.WriteLine("Event is subscribed from the 
            service at {0}",DateTime.Now.ToString() );
        }
  
    }
Step 11: Main method of the client side you can find the creating Subscription instance and it passed to service using InstanceContext
 static void Main(string[] args)
        {
            IMyEvents evnt = new MySubscriber();
            InstanceContext evntCntx = new InstanceContext(evnt);

            EventServiceClient proxy = new EventServiceClient(evntCntx);
            Console.WriteLine("Client subscribe the event
             from the service at {0}",DateTime.Now.ToString());
            proxy.SubscribeEvent();
            Console.WriteLine("Client call operation which will fire the event");
            proxy.DoSomethingAndFireEvent();
            Console.ReadLine();
        }
Step 12: Run the client application and you see the when event is fired from the service. Subscriber got notification.

Callback Service

Till now we have seen that the all clients will call the service to get the things done. But WCF also provides the service to call the client. In which, service will act as client and client will act as service.
  • HTTP protocols are connectionless nature, so it is not supported for callback operation. So BasicHttpBinding and WSHttpBinding cannot be used for this operation.
  • WCF support WSDualHttpBinding for call back operation.
  • All TCP and IPC protocols support Duplex communication. So all these binding will be used for callback operation.

Defining and configuring a callback contract

Callback service can be enabled by using CallbackContract property in the ServiceContract attribute. In the below example you can find the decalration of the callback contract and it is configured in the ServiceContract attribute.
    public interface IMyContractCallback
    {
        [OperationContract]
        void OnCallback();
    }
    [ServiceContract(CallbackContract = typeof(IMyContractCallback))]
    public interface IMyContract
    {
        [OperationContract()]
        void MyMethod();
    }

Client Callback Setup

As I said earlier, in callback operation client will act as service and service will act as client. So client has to expose a callback endpoint to the service to call. In the earlier part of the tutorial I have mention that InstanceContext is the execution scope of inner most service instance. It provides a constructor that takes the service instance to the host.
 IMyContractCallback callback=new MyCallback();
        InstanceContext cntx=new InstanceContext(callback);

        MyServiceClient proxy = new MyServiceClient(cntx);
        proxy.MyMethod();   
The client must use a proxy that will set up the bidirectional communication and pass the callback endpoint reference to the service. This can be achieved by creating the proxy using DuplexClientBase
   class MyServiceClient:DuplexClientBase,IMyContract
    {
        public MyServiceClient(InstanceContext callbackCntx)
            : base(callbackCntx)
        {            
        }
        public void MyMethod()
        {
             base.Channel.MyMethod();
        }
    }

Service-Side Callback Invocation

The client-side callback endpoint reference is passed along with every call the client makes to the service, and it is part of the incoming message. The OperationContext class provides the service with easy access to the callback reference via the generic method GetCallbackChannel<T>( ). Service can call the client side callback method using reference e to the client side callback instance. The following code shows the callback method invocation.
IMyContractCallback
 callbackInstance=OperationContext.Current.GetCallbackChannel();
            callbackInstance.OnCallback();

One-Way

In One-Way operation mode, client will send a request to the server and does not care whether it is success or failure of service execution. There is no return from the server side, it is one-way communication.
Client will be blocked only for a moment till it dispatches its call to service. If any exception thrown by service will not reach the server.
Client can continue to execute its statement, after making one-way call to server. There is no need to wait, till server execute. Sometime when one-way calls reach the service, they may not be dispatched all at once but may instead be queued up on the service side to be dispatched one at a time, according to the service's configured concurrency mode behavior. If the number of queued messages has exceeded the queue's capacity, the client will be blocked even if it's issued a one-way call. However, once the call is queued, the client will be unblocked and can continue executing, while the service processes the operation in the background.

Definition :

One-way operation can be enabled by setting IsOneWay property to true in Operation contract attribute.
[ServiceContract]
public interface IMyService
{
    [OperationContract(IsOneWay=true)]
    void MyMethod(EmployeeDetails emp);
}

One-Way Operations and Sessionful Services

Let us see the example, what will happen when you use the one-way communication with Sessionful service.
    [ServiceContract(SessionMode = SessionMode.Required)]
    interface IMyContract
    {
        [OperationContract(IsOneWay = true)]
        void MyMethod();
    }
As per above configuration, when client makes one-way call using MyMethod() operation and if it close the proxy. Client will be blocked until operation completes. It will be good practice, that one-way operation should be applied on per-call and singleton service.
Suppose If you want to make use of One-way operation in Sessionful service, use in the last operation of the service which will terminate the session. This operation should not return any value.
    [ServiceContract(SessionMode = SessionMode.Required)]
    interface IMyContract
    {
        [OperationContract]
        void MyMethod1();

        [OperationContract]
        string MyMethod2();

        [OperationContract(IsOneWay = true, IsInitiating = false,
                                           IsTerminating = true)]
        string CloseSessionService(int id);
       
    }

One-Way Operations and Exceptions

Suppose when we are using BasicHttpBinding or WSHttpBinding, i.e. no transport session is used, if any exception throw by service will not affect the client. Client can make a call to the service using same proxy
[ServiceContract]
interface IMyContract
{
   [OperationContract(IsOneWay = true)]
   void MethodWithError( );

   [OperationContract]
   void MethodWithoutError( );
}
//Client side without transport session
MyContractClient proxy = new MyContractClient( );
proxy.MethodWithError( ); //No exception is thrown from serivce
proxy.MethodWithoutError( ); //Operation will execute properly
proxy.Close( );
In the presence of transport session, any exception thrown by service will fault the client channel. Client will not be able to make new call using same proxy instance.
//Client side transport session
MyContractClient proxy = new MyContractClient( );
proxy.MethodWithError( ); 
proxy.MethodWithoutError( ); //Can not executre because channel is faulted
proxy.Close( );

Oprations =Request-Reply

By default all WCF will operated in the Request-Replay mode. It means that, when client make a request to the WCF service and client will wait to get response from service (till receiveTimeout). After getting the response it will start executing the rest of the statement. If service doesn't respond to the service within receiveTimeout, client will receive TimeOutException.
Apart from NetPeerTcpBinding and the NetMsmqBinding all other bindings will support request-reply operations.

Throttling

WCF throttling provides some properties that you can use to limit how many instances or sessions are created at the application level. Performance of the WCF service can be improved by creating proper instance.
Attribute Description
maxConcurrentCalls Limits the total number of calls that can currently be in progress across all service instances. The default is 16.
maxConcurrentInstances The number of InstanceContext objects that execute at one time across a ServiceHost. The default is Int32.MaxValue.
maxConcurrentSessions A positive integer that limits the number of sessions a ServiceHost object can accept. The default is 10.
Service Throttling can be configured either Adminstractive or Programatically

Administrative(configuration file)

Using <serviceThrottling> tag of the Service Behavior, you can configure the maxConcurrentCalls, maxConcurrentInstances , maxConcurrentSessions property as shown below.
<system.serviceModel>
    <services >
      <service behaviorConfiguration="ServiceBehavior"  name="MyService">
        <endpoint address="" binding="wsHttpBinding" contract="IMyService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true "/>
          <serviceThrottling maxConcurrentCalls="500"
 maxConcurrentInstances ="100" 
maxConcurrentSessions ="200"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Programming Model

Use ServiceThrottlingBehavior object to set concurrent calls, session and instance property.
           ServiceHost host = new ServiceHost(typeof(MyService));
           ServiceThrottlingBehavior throttle
 = host.Description.Behaviors.Find();
            if (throttle == null)
            {
                throttle = new ServiceThrottlingBehavior();
                throttle.MaxConcurrentCalls = 500;
                throttle.MaxConcurrentSessions = 200;
                throttle.MaxConcurrentInstances = 100;
                host.Description.Behaviors.Add(throttle);
            }

            host.Open();