Search...

Wednesday, August 21, 2013

KnownType attribute in WCF

The KnownTypeAttribute class allows you to specify, in advance, the types that should be included for consideration during deserialization. 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. 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 hash table. When serializing these types, the receiving side cannot determine in advance the data contract for these members.

Let’s say you have the following classes:

1. Account

2. Users (derives from Account)

3. Guest (derives from Account)

If you mark each class with the DataContract attribute and create a service operation that returns a User type, you will be able to return a User, but not a Guest. If you try to return it, you’ll receive either a serialization error (On the server side) or a strange client-side error.

To fix this problem you decorate your base class Account with the KnownType attribute to tell the outside world what a Account can look like.


     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
        [DataContract]
        [KnownType(typeof(User))]
        [KnownType(typeof(Guest))]
        public class Account
        {
            [DataMember]
            public String UserId { get; set; }
        }
    
        [DataContract]
        public class User : Account
        {
            [DataMember]
            public String Name { get; set; }
    
            [DataMember]
            public String Password { get; set; }
        }
    
        [DataContract]
        public class Guest : Account
        {
            [DataMember]
            public String Name { get; set; }
        }
    

    Once you decorate your Account class with every known derived type, you can return these types from your service.(Download)

    Tuesday, August 20, 2013

    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.

    Transaction attributes in the System.ServiceModel namespace allow you to do the following:
    1. Configure transaction time-outs and isolation-level filtering using the ServiceBehaviorAttribute attribute.
    2. Enable transactions functionality and configure transaction completion behavior using the OperationBehaviorAttribute attribute. 
    3. Use the ServiceContractAttribute and OperationContractAttribute attributes on a contract method to require, allow or deny transaction flow.
    How to Configure Transaction in WCF?

    There are some factors that need to be considered while configuring a transaction in WCF.

    Binding :There are only few bindings in WCF that can support transaction, these are

    NetTcpBinding,

    NetNamedPipeBinding,

    WSHttpBinding,

    WSDualHttpBinding
    , and

    WSFederationHttpBinding


    So, in order to configure transaction, one has to make a choice out of such bindings. Though these bindings do have transaction support but by default it is disabled, so one has to make them enabled.

    Operation Contract and behavior : An appropriate binding merely makes a way to propagate transaction from client to service but at service there is only an operation/method that is going to take care of that. So, the next step is to configure an operation. Operations are configured generally with the following two attributes:

    A) TransactionFlow : This attribute is set with a parameter named TransactionFlowOption which has three values. Its values are self descriptive:
    1. Allowed – Implies if client has transaction, it will be accepted otherwise not a problem.
    2. NotAllowed – Client cannot send transaction to server while calling a method.
    3. Mandatory – Client has to create a transaction otherwise the method cannot be called.
    B) TransactionScopeRequired : This OperationBehavior depicts whether the method/operation should do its work inside a transaction

    While developing a Service Contract you have to specify the TransactionFlow attribute on each
    Operation Contracts that requires a Transaction to be handled. In the below code snippet there are two methods one which submit employee master information and the other that submits employee details. As both require transaction so I have specified TransactionFlow attribute on both of them.


    Transaction is basically a logical unit of work comprising of activities that all needed to be succeeded or failed, and also it must be compliant with ACID principals.
    
    Movement of money from a bank account to another is a simple example of a transaction. In this single transaction, two operations will be performed. One account will be debited (amount will be 
    taken from) and other will be credited (amount will be deposited).
    
    Enabling transactions in Windows Communication Foundation is simple and straight forward but implementation sometimes becomes difficult depending upon the scenario. For example, implementing transactions in a distributed environment will definitely require effort and more things to consider.
    
    Now, consider we already have developed a WCF service and we wanted to enable transactions on it. So, we will follow the steps below:
    
    
    1. Add System.Transactions namespace to WCF Service project.
    2. Set TransactionFlow property of the OperationContract attribute to Mandatory.  Available options for TransactionFlow are: a. Mandatory - transaction must be flowed b. Allowed - transaction may be flowed c. Not Allowed - transaction is not flowed For example, our WCF service contract as follows: [TransactionFlow(TransactionFlowOptions.Mandatory] void MyMethod();
    3. Now, set the OperationBehavior attribute for the implementing method. [OperationBehavior(TransactionScopeRequired=true, TransactionAutoComplete=true)] void MyMethod() { } TransactionScopeRequired = true means it can only be called in a transaction. TransactionAutoComplete = true means that if the operation completes successfully, transaction will be committed. 
    4. Enable Transactions for WCF Binding being used. For Example, In our configuration file bindings will be as follows: <bindings>   <wsHttpBinding>      <binding name=”httpBinding”  transactionFlow=”true” />   </ wsHttpBinding > </bindings>  Remember that we must choose a binding that supports transactions i.e. netTcpBinding, netNamedPipeBinding, wsHttpBinding, wsDualHttpBinding, and wsFederationHttpBinding.
    5. Need to start the transaction from client as: using System.Transaction; Using( var transScope = new TransactionScope()) {          //Calling service methods      IMyServiceClient client = new IMyServiceClient();      client.MyMethod();            transScope.complete();      }
    Optionally, If we wanted to specify the Isolation level for the transaction, we can add serviceBehaviorattribute to implementing class as follows: [ServiceBehavior(TransactionIsolationLevel=System.Transaction.IsolationLevel.Serializable)] Public class MyService : IMyService{}  This is all we need to do for enabling transactions in WCF.

    Friday, August 16, 2013

    Create Custom Windows in WPF

    In this article, I am demonstrating how to create a custom window theme visually using declarative XAML and apply it to windows in your applications.

    You can download the full source code here.

    The first thing you may want to do in creating a custom window is to actually create a visual template.

    The following extension points are supported for current implementation:

    1. PART_TITLEBAR (UIElement) - For displaying window title, dragging and maximize / restore operations.
    2. PART_MINIMIZE (Button) – Window minimize button
    3. PART_MAXIMIZE_RESTORE (Button) – Maximize restore button
    4. PART_CLOSE (Button) – Close button
    5. PART_LEFT_BORDER (UIElement) – Left resizable border
    6. PART_RIGHT_BORDER (UIElement) – Right resizable border
    7. PART_TOP_BORDER (UIElement) – Top resizable border
    8. PART_BOTTOM_BORDER (UIElement) – Bottom resizable border

    One more thing to note is that while defining the window template, you must declare the ContentPresenter(which ultimately contains window content) within AdornerDecorator tag (which is the adorner layer for the window) as this is a WPF requirement.

    Here is the template I have created.


    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        x:Class="CustomWindow.Resources.Themes.Style">

        <Style TargetType="{x:Type ToolTip}">
            <Setter Property = "Background" Value="#fdfbb6"/>
            <Setter Property = "Foreground" Value="Black"/>
            <Setter Property = "FontSize" Value="12"/>
            <Setter Property = "FontWeight" Value="DemiBold"/>
        </Style>

        <Style TargetType="{x:Type StatusBar}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type StatusBar}">
                        <Border Name="Border" BorderBrush="#BFE3FE" BorderThickness="1" CornerRadius="0" Padding="0" Margin="0">
                            <Border.Background>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                    <GradientStop Color="#FFb7b7b7" Offset="1"/>
                                    <GradientStop Color="#FFF1EDED" Offset="0"/>
                                </LinearGradientBrush>
                            </Border.Background>
                            <ItemsPresenter Margin="-3"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="WinButton" TargetType="{x:Type Button}">
            <Setter Property="Margin" Value="0,0,4,0" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="Height" Value="20" />
            <Setter Property="Width" Value="20" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="true">
                    <Setter Property="Cursor" Value="Hand" />
                </Trigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="WinTitle" TargetType="{x:Type Label}">
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Foreground" Value="Black" />
        </Style>

        <LinearGradientBrush x:Key="WinBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Offset="0" Color="White" />
                    <GradientStop Offset="1" Color="GhostWhite" />
                </GradientStopCollection>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>

        <LinearGradientBrush x:Key="WinBackground" StartPoint="0,0" EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop Offset="0" Color="White" />
                    <GradientStop Offset="1" Color="Silver" />
                </GradientStopCollection>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>

        <SolidColorBrush x:Key="WinBorderBrush" Color="Silver"/>

        <Style x:Key="WindowStyle" TargetType="{x:Type Window}">
            <Setter Property="FontSize" Value="12" />
            <Setter Property="Height" Value="25" />
            <Setter Property="Width" Value="100" />
            <Setter Property="ShowActivated" Value="True"/>
            <Setter Property="ResizeMode" Value="NoResize"/>
            <Setter Property="WindowState" Value="Normal"/>
            <Setter Property="ResizeMode" Value="NoResize" />
            <Setter Property="WindowStyle" Value="None" />
            <Setter Property="AllowsTransparency" Value="True" />
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Window}">
                        <Grid MouseLeftButtonDown="Window_MouseLeftButtonDown">
                            <Border BorderThickness="1" Background="{DynamicResource WinBackgroundBrush}" BorderBrush="{DynamicResource WinBorderBrush}">
                                <DockPanel LastChildFill="True">
                                    <Border x:Name="PART_TITLEBAR" 
                                            Margin="0" 
                                            Height="30" 
                                            DockPanel.Dock="Top" 
                                            CornerRadius="10" 
                                            Background="Transparent">
                                        <DockPanel LastChildFill="False" Background="{DynamicResource WinBackground}" Margin="0">
                                            <Image Source="{TemplateBinding Icon}" Height="20" Width="20"/>
                                            <TextBlock Padding="8,0,0,4" 
                                                       Margin="0"
                                                       VerticalAlignment="Center" 
                                                       FontStretch="UltraExpanded" 
                                                       Foreground="Black" 
                                                       TextTrimming="CharacterEllipsis" 
                                                       TextWrapping="NoWrap" 
                                                       Text="{TemplateBinding Title}"
                                                       FontWeight="DemiBold"
                                                       FontSize="16"/>
                                            <Button x:Name="PART_CLOSE" 
                                                    DockPanel.Dock="Right" 
                                                    ToolTip="Close"
                                                    Click="PART_CLOSE_Click"
                                                    Style="{DynamicResource WinButton}">
                                                <Image Source="../Images/close.png"/>
                                            </Button>
                                            <Button x:Name="PART_MAXIMIZE_RESTORE" 
                                                    DockPanel.Dock="Right"
                                                    ToolTip="Maximize"
                                                    Click="PART_MAXIMIZE_RESTORE_Click"
                                                    Style="{DynamicResource WinButton}">
                                                <Image Source="../Images/max.ico"/>
                                            </Button>
                                            <Button x:Name="PART_MINIMIZE" 
                                                    DockPanel.Dock="Right"
                                                    ToolTip="Minimize"
                                                    Click="PART_MINIMIZE_Click"
                                                    Style="{DynamicResource WinButton}">
                                                <Image Source="../Images/min.png"/>
                                            </Button>
                                        </DockPanel>
                                    </Border>

                                    <AdornerDecorator DockPanel.Dock="Bottom">
                                        <ContentPresenter Content="{TemplateBinding Content}" Margin="{TemplateBinding Margin}" DataContext="{TemplateBinding DataContext}" ContextMenu="{TemplateBinding ContextMenu}"/>
                                    </AdornerDecorator>

                                </DockPanel>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </ResourceDictionary>

    The window created looks like the following: