Sunday, August 16, 2015

.Net Sound Timer

This tutorial show you how to set sound timer depend on the number of order. It plays sound for notification whenever the number of order change.
Sound Timer

Firstly, copy the following javascript to <head> tage.
<script type="text/javascript">
    function EvalSound(soundobj) {
        var thissound = document.getElementById(soundobj);
        thissound.play();
    }
</script>
Secondly, copy the following code to <form> tag.
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:Timer ID="Timer1" runat="server" Interval="5000" OnTick="Timer1_Tick">
</asp:Timer>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:Label ID="lblOrder" runat="server" Text=""></asp:Label>
    </ContentTemplate>
    <Triggers>
        <asp:AsyncPostBackTrigger ControlID="Timer1" />
    </Triggers>
</asp:UpdatePanel>
<audio id="audio1" src="sound/Console_beep.mp3" preload="auto" autobuffer>
</audio>
In code-behind, the following snippet should be there.
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string dt = DateTime.Now.ToLongTimeString();
        string count = DAL.GetOrderCount();
        lblOrder.Text = string.Format("There are {0} records at {1}.", count, dt);
        Session["count"] = count;
        
    }
}
protected void Timer1_Tick(object sender, EventArgs e)
{
    string dt = DateTime.Now.ToLongTimeString();
    string count = DAL.GetOrderCount();
    if (count != Session["count"].ToString())
    {
        lblOrder.Text = string.Format("There are {0} records at {1}.", count, dt);
        ScriptManager.RegisterStartupScript(Page, GetType(), "PlaySound", "EvalSound('audio1');", true);
    }
    Session["count"] = count;
}
It uses "Northwind" database and connection string in web.config seem like below:
<connectionStrings>
<add name="sqlConn" providerName="System.Data.SqlClient" connectionString="Server='(local)';uid='sa';pwd='p@ssw0rd';Database='Northwind';Pooling=False;" />
</connectionStrings>
It has the following code snippet in the DAL class. It uses the Microsoft.Practices.EnterpriseLibrary.Data.dll to shorten the code.
private static Database getDatabase()
{
    Database database = null;
    try
    {
        database = DatabaseFactory.CreateDatabase("sqlConn");
    }
    catch (Exception exception)
    {
               
    }
    return database;
}
public static string GetOrderCount()
{
    string count = "";
    try
    {
        count = getDatabase().ExecuteScalar("GetOrderCount").ToString();
    }
    catch (Exception exception)
    {
        
    }
    return count;
}
The "GetOrderCount" stored procedure is as shown below:
USE [Northwind]
GO
ALTER PROCEDURE [dbo].[GetOrderCount]
AS
BEGIN
    SELECT COUNT(*) FROM Orders;
END
This application demonstrates a simple use of the Timer control with UpdatePanel combining HTML5 audio element in a real world example.

Sunday, April 12, 2015

ASP.NET ListView Custom Paging with DataPager

When displaying large amounts of data it's often best to only display a portion of the data, allowing the user to step through the data ten or so records at a time. While default paging was easy to implement, it carried with it a performance cost since all records to be paged through were being returned from the database.Custom paging solved this performance issue by requiring the page developer to tell the ListView exactly how many total records were being paged through as well as returning the precise subset of records to display on the page. The following example use ObjectDataSource for DAL and Microsoft.Practices.EnterpriseLibrary.Data.dll (download here) to shorten code.
ListView Custom Paging
Copy the following code to <head> tag.
<head runat="server">
    <title>ListView Test</title>
    <style type="text/css">
        .imgborder {
            border-color: #CCC;
            border-width: thin;
            border-style: solid;
            margin: 5px;
            padding: 5px;
        }
    </style>
</head>  
Here is server controls and copy to <form> tag.
<asp:ListView ID="ListView1" runat="server" GroupItemCount="4" GroupPlaceholderID="groupPlaceHolder1"
      ItemPlaceholderID="itemPlaceHolder1" DataSourceID="ObjectDataSource1" OnPagePropertiesChanging="ListView1_PagePropertiesChanging">
      <LayoutTemplate>
          <table>
               <asp:PlaceHolder runat="server" ID="groupPlaceHolder1"></asp:PlaceHolder>
          </table>
      </LayoutTemplate>
      <GroupTemplate>
          <tr>
              <asp:PlaceHolder runat="server" ID="itemPlaceHolder1"></asp:PlaceHolder>
          </tr>
      </GroupTemplate>
      <ItemTemplate>
           <td class="imgborder">
               <asp:Label ID="lblCustomerID" runat="server" Text='<%#Eval("CustomerID") %>' /></br>
               <asp:Label ID="lblCompanyName" runat="server" Text='<%#Eval("CompanyName") %>' /><br>
               <asp:Label ID="lblContactName" runat="server" Text='<%#Eval("ContactName") %>' />
           </td>
      </ItemTemplate>
      <EmptyDataTemplate>
          There is no data.
      </EmptyDataTemplate>
 </asp:ListView>
 <asp:DataPager ID="DataPager1" runat="server" PageSize="8" PagedControlID="ListView1">
      <Fields>
           <asp:NumericPagerField />
      </Fields>
 </asp:DataPager>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GridDataPage"
    TypeName="DAL" SelectCountMethod="DataRowCount" 
    SortParameterName="SortExpression" EnablePaging="True">
    <SelectParameters>
        <asp:Parameter Name="maximumRows" Type="Int32" />
        <asp:Parameter Name="startRowIndex" Type="Int32" />
        <asp:Parameter Name="SortExpression" Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>
In code-behind, "ListView1_PagePropertiesChanging" event is as below:
protected void ListView1_PagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
    DataPager1.SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
    ListView1.DataBind();
}
Here is the connection string in web.config and it use sample "Northwind" db (download here) and "Customers" table.
<connectionStrings>
    <add name="sqlConn" providerName="System.Data.SqlClient"  connectionString="Server='.\SQLEXPRESS';uid='xxxxxx';pwd='xxxxxxxx';Database='Northwind';Pooling=False;"/>
</connectionStrings>
Here is the underlying DAL class for ObjectDataSource.
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;
public class DAL
{
    // Methods
    private static Database getDatabase()
    {
        Database database = null;
        try
        {
            database = DatabaseFactory.CreateDatabase("sqlConn");
        }
        catch (Exception ex)
        {
            //handle exception here.
        }
        return database;
    }
    public static DataSet GridDataPage(int maximumRows, int startRowIndex, string SortExpression)
    {
        DataSet ds = new DataSet();
        if (startRowIndex >= maximumRows)
        {
            startRowIndex++;
        }
        try
        {
            ds = getGridData(maximumRows, startRowIndex, SortExpression);
            if (ds != null && ds.Tables[0].Rows.Count > 0)
            {
                startRowIndex = (startRowIndex > 0) ? startRowIndex : 1;
                for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                {
                    ds.Tables[0].Rows[i][0] = Convert.ToString((int)(i + startRowIndex));
                }
                HttpContext.Current.Items["rowCount"] = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
                return ds;
            }
            HttpContext.Current.Items["rowCount"] = 0;
        }
        catch (Exception ex)
        {
            //handle exception here.
        }
        return ds;
    }
    public static DataSet getGridData(int maximumRows, int startRowIndex, string SortExpression)
    {
        DataSet ds = new DataSet();
        try
        {
            ds = getDatabase().ExecuteDataSet("GetCustomers", new object[] { maximumRows, startRowIndex, SortExpression });
        }
        catch (Exception ex)
        {
            ds = null;
            //handle exception here.
        }
        return ds;
    }
    public static int DataRowCount(int maximumRows, int startRowIndex, string SortExpression)
    {
        return (int)HttpContext.Current.Items["rowCount"];
    }
}
Here is transact-sql (store procedure).
USE [Northwind]
GO
ALTER PROCEDURE [dbo].[GetCustomers]
    @pageSize INT = NULL,
    @pageStart INT = NULL,
    @orderBy nvarchar(200) = NULL
AS
BEGIN

DECLARE @sqlPopulate VARCHAR(2000)
IF @pageSize IS NULL or @pageSize = 0
    SET @pageSize = 10;
IF @pageStart IS NULL
    SET @pageStart = 0;
IF @orderBy IS NULL OR @orderBy = '' 
    SET @orderBy = 'CustomerID DESC';
IF @pageStart = 0
BEGIN
    SET @sqlPopulate = 'SELECT '' '' AS No, CustomerID, CompanyName, ContactName, ContactTitle ' +
        + ' FROM dbo.Customers WHERE CustomerID IN '+
        '(SELECT top '+ CAST(@pageSize AS VARCHAR(10)) +' CustomerID FROM dbo.Customers ';

    SET @sqlPopulate = @sqlPopulate + ' ORDER BY ' + @orderBy +
        ') ORDER BY ' + @orderBy;
END
ELSE
BEGIN
    SET @sqlPopulate = 'SELECT '' '' AS No, CustomerID, CompanyName, ContactName, ContactTitle ' +
        ' FROM Customers WHERE CustomerID IN '+
        '(SELECT top '+ CAST(@pageSize AS VARCHAR(10)) + ' CustomerID FROM Customers WHERE CustomerID NOT IN '+
            '(SELECT top '+ CAST((@pageStart-1) AS VARCHAR(10)) +' CustomerID FROM Customers ';

    SET @sqlPopulate = @sqlPopulate + ' ORDER BY ' + @orderBy +
            ') ORDER BY ' + @orderBy + ') ORDER BY ' + @orderBy;
END
EXEC(@sqlPopulate)

SET @sqlPopulate = '';
SET @sqlPopulate = 'SELECT COUNT(*) FROM Customers';
EXEC (@sqlPopulate)
END 
That's it. Happy Myanmar New Year!!!

Sunday, December 7, 2014

GridView Custom Paging and Sorting Using LINQ

When displaying large amounts of data it's often best to only display a portion of the data, allowing the user to step through the data ten or so records at a time. Additionally, the end user's experience can be enhanced if they are able to sort the data by one of the columns. Custom paging and sorting is the best solution for this case. You can see the gridview custom paging and sorting using T-SQL post here. In this article I will explain how to populate the ASP.Net GridView control from database using LINQ and how to sort GridView row using its SortExpression property. For this sample to work you will need to download the Microsoft Northwind database here.
GridView Custom Paging and Sorting

First, open Visual Studio 2013 and create one project "WebAppBlog" and then add Class Library "Northwind" as follows:

Inside "Northwind" project, add ADO.NET Entity Data Model as below:

After adding "Northwind.edmx", build the project.

Secondly, create one more Class Library "WebAppBlog.Process".
  

Add Reference "EntityFramework" from  "YourProjectsFolder\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll"and "Northwind" from Northwind project as shown below:
Create "Customer.cs" and replace the following code with existing:
using Northwind;
namespace WebAppBlog.Process
{
    public class Customer
    {
        #region Pager
        private int numberOfRecords;
        public int NumberOfRecords
        {
            get { return numberOfRecords; }
            internal set { numberOfRecords = value; IsDirty = true; }
        }

        private int pageSize;
        public int PageSize
        {
            get { return pageSize; }
            internal set { pageSize = value; IsDirty = true; }
        }

        private int currentPageIndex;
        public int CurrentPageIndex
        {
            get { return currentPageIndex; }
            internal set { currentPageIndex = value; IsDirty = true; }
        }
        public string SortExpression { get; private set; }
        public bool IsSortDescending { get; private set; }
        #endregion

        public bool IsDirty { get; set; }
        public List<CustomerDto> CustomerList;
        public void Initialize()
        {
            CurrentPageIndex = 0;
            NumberOfRecords = 0;
            PageSize = 10;
            SortExpression = "CustomerID";
            IsSortDescending = true;

            CustomerList = new List<CustomerDto>();
            IsDirty = false;

        }
        public void Paginate(int pageIndex)
        {
            CurrentPageIndex = pageIndex;
            GetCustomerList();
        }
        public void ResetPageSize(int pageSize)
        {
            PageSize = pageSize;
            CurrentPageIndex = 0;
            GetCustomerList();
        }
        public void Sort(string sortExp)
        {
            IsSortDescending = SortExpression == sortExp ? !IsSortDescending : false;
            SortExpression = sortExp;
            GetCustomerList();
        }
        public void GetCustomerList()
        {
            CustomerList.Clear();
            using (NorthwindEntities context = new NorthwindEntities())
            {
                NumberOfRecords = context.Customers.Count();
                IEnumerable<Northwind.Customer> allCustomerList = context.Customers.ToList();
                IList<Northwind.Customer> customerList = new List<Northwind.Customer>();
               
                if(NumberOfRecords > 0)
                     customerList = GetSortedandPaginatedResult(allCustomerList);

                foreach(var c in customerList)
                {
                    CustomerList.Add(new CustomerDto
                        {
                            CustomerId = c.CustomerID,
                            CompanyName = c.CompanyName,
                            ContactName = c.ContactName,
                            ContactTitle = c.ContactTitle,
                            City = c.City
                        });
                }
            }
        }
        private List<Northwind.Customer> GetSortedandPaginatedResult(IEnumerable<Northwind.Customer> allCustomer)
        {
            var result = new List<Northwind.Customer>();
            if(SortExpression == "CustomerID")
            {
                result = IsSortDescending ? allCustomer.OrderByDescending(o => o.CustomerID).ToList() : 
                    allCustomer.OrderBy(o => o.CustomerID).ToList();
            }
            else if(SortExpression == "ContactName")
            {
                result = IsSortDescending ? allCustomer.OrderByDescending(o => o.ContactName).ToList() : 
                    allCustomer.OrderBy(o => o.ContactName).ToList();
            }
            result = result.Skip(CurrentPageIndex * PageSize).Take(PageSize).ToList();
            return result;
        }
        public class CustomerDto
        {
            public string CustomerId { get; set; }
            public string CompanyName { get; set; }
            public string ContactName { get; set; }
            public string ContactTitle { get; set; }
            public string City { get; set; }
        }

    }
}
After adding "Customer.cs", build the project.
Finally, go to "WebAppBlog" project and add Reference "WebAddBlog.Procecss" and then create "Customer.aspx" page and add the Gridview control as follows:
<asp:GridView ID="gvCustomer" runat="server" AllowCustomPaging="True" AllowPaging="True" 
 AutoGenerateColumns="False" OnPageIndexChanging="gvCustomer_PageIndexChanging" 
 AllowSorting="True" OnSorting="gvCustomer_Sorting">
 <Columns>
  <asp:BoundField DataField="CustomerID" HeaderText="ID" SortExpression="CustomerID" />
  <asp:BoundField DataField="CompanyName" HeaderText="Company Name" />
  <asp:BoundField DataField="ContactName" HeaderText="Contact Name" SortExpression="ContactName" />
  <asp:BoundField DataField="ContactTitle" HeaderText="Contact Title" />
  <asp:BoundField DataField="City" HeaderText="City" />
 </Columns>
 <EmptyDataTemplate>
  <asp:Label ID="Label1" runat="server" Text="No data"></asp:Label>
 </EmptyDataTemplate>
</asp:GridView>
In code-behind, replace the following code with existing one:
public WebAppBlog.Process.Customer Model
{
    get { return Session["ICustomer"] as WebAppBlog.Process.Customer; }
    set { Session["ICustomer"] = value; }
}

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
        InitModel();
}

private void InitModel()
{
    Model = new WebAppBlog.Process.Customer();
    Model.Initialize();
    Model.GetCustomerList();

}
protected void Page_Prerender(object sender, EventArgs e)
{
    BindModel();
}

private void BindModel()
{
    if (Model.IsDirty)
    {
        gvCustomer.VirtualItemCount = Model.NumberOfRecords;
        gvCustomer.PageIndex = Model.CurrentPageIndex;
        gvCustomer.PageSize = Model.PageSize;
        gvCustomer.DataSource = Model.CustomerList;
        gvCustomer.DataBind();

        Model.IsDirty = false;
       
    }
}
protected void gvCustomer_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    Model.Paginate(e.NewPageIndex);
}

protected void gvCustomer_Sorting(object sender, GridViewSortEventArgs e)
{
    Model.Sort(e.SortExpression);
}
That's it. Thank you! Happy Christmas!

Monday, September 1, 2014

How to create Alert Message Box for the whole application

We often have to display Alert Dialog for the end user to show message about information or error. Here I show you how to create Alert Message Box using ModalPopupExtender in User Control. By using User Control and Master Page, it can be re-used elsewhere in the site.
Alert Message Box
First, create the user control (AlertMessage.ascx) and then add CSS and the server control as below :
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<style type="text/css">
    .modalPopup
    {
        background-color: #ffffdd;
        border-width: 3px;
        border-style: solid;
        border-color: Gray;
        padding: 3px;
        width: 350px;
        border-radius: 5px;
    }
    .modalBackground
    {
        background-color: Gray;
        filter: alpha(opacity=70);
        opacity: 0.7;
    }
</style>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <asp:HiddenField ID="hfMessage" runat="server"></asp:HiddenField>
        <asp:Panel ID="Panel1" runat="server"  CssClass="modalPopup">
            <table style="width : 100%;">
                <tr>
                    <td>
                        <asp:Label ID="lblMessage" runat="server" Text="Label"></asp:Label>
                    </td>
                </tr>
                <tr>
                    <td>&nbsp;</td>
                </tr>
                <tr align="center">
                    <td>
                        <asp:Button ID="btnOK" runat="server" Text="OK"/>
                    </td>
                </tr>
            </table>
        </asp:Panel>
        <asp:ModalPopupExtender ID="ModalPopupExtender1" runat="server" BackgroundCssClass="modalBackground"
            PopupControlID="Panel1" TargetControlID="hfMessage" OkControlID="btnOK" Enabled="True">
        </asp:ModalPopupExtender>
    </ContentTemplate>
</asp:UpdatePanel>
In code-behind, create property and function as shown below :
public event EventHandler MessagePostback
{
    add { btnOK.Click += value; }
    remove { btnOK.Click -= value; }
}
public string UrlPostback
{
    get { return hfMessage.Value; }
    set { hfMessage.Value = value;}
}
public void ShowMessage(string msg, string urlPostback = "")
{
    try
    {
        lblMessage.Text = msg;
        UrlPostback = urlPostback;
        if (string.IsNullOrEmpty(msg)) return;
        if(!string.IsNullOrEmpty(urlPostback))
            ModalPopupExtender1.OkControlID = string.Empty;

        btnOK.Focus();
        ModalPopupExtender1.Show();
        UpdatePanel1.Update();
    }
    catch(Exception ex)
    {
        lblMessage.Text = ex.GetBaseException().Message;
        UpdatePanel1.Update();
        return;
    }
}
Then, create Master page (MasterPage.master) and then add ScriptManager and the user control we created as below:
<form id="form1" runat="server">
<asp:ScriptManager ID="Scriptmanager1" runat="server">
</asp:ScriptManager>
<div>
    <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
    </asp:ContentPlaceHolder>
</div>
<uc1:AlertMessage ID="AlertMessage1" runat="server" OnMessagePostback="AlertMessage1_PostBack" />
</form>
In code-behind, create one method and one event handler as follow :
public void ShowMessage(string msg, string urlPostBack= "")
{
    AlertMessage1.ShowMessage(msg, urlPostBack);
}
protected void AlertMessage1_PostBack(object sender, EventArgs e)
{
    if (!string.IsNullOrEmpty(AlertMessage1.UrlPostback))
        Response.Redirect(AlertMessage1.UrlPostback);
}
Next, create one .aspx page (TestMessage.aspx) using Master Page we created before and add "MasterType" directive to call Master Page's method as below :
<%@ MasterType VirtualPath="~/MasterPage.Master" %>
In code-behind, copy the following code to Page_Load event as shown below :
protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        try
        {
            throw new ApplicationException("This is test.");
        }
        catch (Exception ex)
        {
             //Call Master's ShowMessage method whenever you want to show Alert Dialog.  
             //Pass the Url parameter when you want redirect to somewhere after OK button press.
             this.Master.ShowMessage(ex.Message, "default.aspx");
        }
    }
}
That's it. When you run "TestMessage.aspx", it show the Alert Message. By clicking "OK" button, it close. Otherwise, it redirect to Url you pass.

Wednesday, March 12, 2014

How to pop up the whole page using Telerik RadWindow

When we use the single page pattern, we have to use Modal Dialog or popup to accept the user input or to display the context information. Here I use the Telerik RadWindow to pop up the whole .aspx page as Modal Dialog Box. RadWindow is a part of the Telerik UI for ASP.NET AJAX suite. It is a container that can display content from the same page (when used as controls container) or it can display a content page, different from the parent one. In the second case, the control uses an IFRAME and behaves like one. This post is related with the second solution.I used the Telerik trial version here and added "Telerik.Web.UI.dll" to my project solution as References.
Dialog box using Telerik RadWindow
First, we need to add the following httpHandler for RadScriptManager to operate properly to web.config as below:
<system.web>        
    ----
    <httpHandlers>   
        ---
        <add path="Telerik.Web.UI.WebResource.axd" verb="*" type="Telerik.Web.UI.WebResource, Telerik.Web.UI" validate="false" />        
    </httpHandlers>    
</system.web> 
Second, we create "TelerikWindow.aspx" page and add the following code to <head> tage:
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
    <script type="text/javascript">
        function openWindow(url) {
            var manager = $find('<%= RadWindowManager1.ClientID %>');
            manager.open(url);
            return false;
        }
        function refreshPage(arg) {
            var ajax = $find('<%= RadAjaxManager.GetCurrent(Page).ClientID %>');
            ajax.ajaxRequest(arg);
        }
    </script> 
</telerik:RadScriptBlock>
Next, add the following code snippet to <form> tage as shown below:
<form id="form1" runat="server">
<telerik:RadScriptManager ID="RadScriptManager1" runat="server" EnablePageMethods="true">
</telerik:RadScriptManager>
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
</telerik:RadAjaxManager>
<div>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
        <ContentTemplate>
            <table>
                <tr>
                    <td>
                        <b>Customer ID:</b>
                    </td>
                    <td>
                        <asp:Label runat="server" ID="lblCustomerID" Text="C00001" />
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Company Name:</b>
                    </td>
                    <td>
                        <asp:Label runat="server" ID="lblCompanyName" Text="Eastern Connection" />
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Contact Name:</b>
                    </td>
                    <td>
                        <asp:Label runat="server" ID="lblContactName" Text="Ann Devon" />
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Country:</b>
                    </td>
                    <td>
                        <asp:Label runat="server" ID="lblCountry" Text="Germany" />
                    </td>
                </tr>
            </table>
            <asp:Button runat="server" ID="btnEditText" Text="Edit text" onclick="btnEditText_Click" />
        </ContentTemplate>
     </asp:UpdatePanel>
</div>
<telerik:RadWindowManager ID="RadWindowManager1" runat="server" Modal="true" ReloadOnShow="true" Width="400px"
    Height="300px" Behaviors="Close, Move">
</telerik:RadWindowManager>
</form> 
In code-behind, add the namespace "Telerik.Web.UI" and replace with the following code :
protected void Page_Load(object sender, EventArgs e)
{
    AjaxRequest();
}
private void AjaxRequest()
{
    RadAjaxManager manager = RadAjaxManager.GetCurrent(this.Page);
    manager.AjaxRequest += new RadAjaxControl.AjaxRequestDelegate(TheRadAjaxManager_AjaxRequest);
}
protected void TheRadAjaxManager_AjaxRequest(object sender, AjaxRequestEventArgs e)
{
    if (e.Argument.ToLower() == "popupclose")
    {
        lblCompanyName.Text = Session["CompanyName"].ToString();
        lblContactName.Text = Session["ContactName"].ToString();
        lblCountry.Text = Session["Country"].ToString();
        UpdatePanel1.Update();
    }
}
protected void btnEditText_Click(object sender, EventArgs e)
{
    Session["CustomerID"] = lblCustomerID.Text;
    Session["CompanyName"] = lblCompanyName.Text;
    Session["ContactName"] = lblContactName.Text;
    Session["Country"] = lblCountry.Text;

    string scriptStr = "openWindow('RadPopup.aspx');";
    ScriptManager.RegisterStartupScript(Page, GetType(), "popup", scriptStr, true);
}
Third, web create "RadPopup.aspx" and copy the following snippet to <head> tag as below:
<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
    <script type="text/javascript">
        function GetRadWindow() {
            var rWindow = null;
            if (window.radWindow)
                rWindow = window.radWindow;
            else if (window.frameElement.radWindow)
                rWindow = window.frameElement.radWindow; 
            return rWindow;
        }
        function Close() {
            GetRadWindow().Close();

        }
        function CloseAndRebind(args) {
            var win = GetRadWindow();
            win.BrowserWindow.refreshPage(args);
            win.Close();
        }
    </script> 
</telerik:RadScriptBlock>
Add the following code to <form> tag :
<form id="form1" runat="server">
<telerik:RadScriptManager ID="RadScriptManager1" runat="server"  EnablePageMethods="true">
</telerik:RadScriptManager>
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
</telerik:RadAjaxManager>
<div>
     <asp:UpdatePanel runat="server" ID="ModalPanel1" RenderMode="Inline" UpdateMode="Conditional">
        <ContentTemplate>
            <table>
                <tr>
                    <td>
                        <b>Customer ID:</b>
                    </td>
                    <td>
                        <asp:Label runat="server" ID="editCustomerID" />
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Company Name:</b>
                    </td>
                    <td>
                        <asp:TextBox runat="server" ID="editTxtCompanyName" />
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Contact Name:</b>
                    </td>
                    <td>
                        <asp:TextBox runat="server" ID="editTxtContactName" />
                    </td>
                </tr>
                <tr>
                    <td>
                        <b>Country:</b>
                    </td>
                    <td>
                        <asp:TextBox runat="server" ID="editTxtCountry" />
                    </td>
                </tr>
            </table>
            <hr />
            <asp:Button ID="btnApply" runat="server" Text="Apply" OnClick="btnApply_Click" />
            <asp:Button ID="editBox_OK" runat="server" Text="OK" OnClick="editBox_OK_Click" />
            <asp:Button ID="editBox_Cancel" runat="server" Text="Cancel" OnClientClick="Close();"/>
        </ContentTemplate>
    </asp:UpdatePanel>
   </div>
</form>
In code-behind, add the namespace "Telerik.Web.UI" and replace the context with the following code snippet as below:
protected void InitDialog()
{
    editCustomerID.Text = Session["CustomerID"].ToString();
    editTxtCompanyName.Text = Session["CompanyName"].ToString();
    editTxtContactName.Text = Session["ContactName"].ToString();
    editTxtCountry.Text = Session["Country"].ToString(); 
    SetFocus("editTxtCompanyName");
}
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        InitDialog();
    }
}
protected void btnApply_Click(object sender, EventArgs e)
{
    if (editTxtCountry.Text == "Germany")
        editTxtCountry.Text = "Cuba";
    else
        editTxtCountry.Text = "USA";
}
protected void editBox_OK_Click(object sender, EventArgs e)
{
    // Save to the database
    // Refresh the UI
    Session["CompanyName"] = editTxtCompanyName.Text;
    Session["ContactName"] = editTxtContactName.Text;
    Session["Country"] = editTxtCountry.Text;

    ScriptManager.RegisterStartupScript(Page, GetType(), "closePopup", "CloseAndRebind('popupclose');", true);
}
Every .aspx page should have the following line directly after the page directive:
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %> 
That's it. Whenever you click "Edit text" button, it pops up "RabPopup.asxp" page and then change the data and press "OK" button, it closes Popup page and then rebind the parent page and update the data to display.

Sunday, January 26, 2014

How to generate the invoice form as PDF file using iTextSharp

We often generate the invoice form as PDF format and send the customer as reference. Microsoft Crystal Report and Telerik Report are handy but expensive for small business. There are other API. Among them, I prefer iTextSharp since it is widely used and lot of examples online. You can download here. I show you how to used iTextSharp for generating PDF as below :
Invoice PDF
Our interface has textboxs and gridview for accepting and displaying Data. It has two options (Download PDF and Send PDF with email). If select the first radio and press "Create PDF" button, it downloads the PDF. Otherwise, it gets the byte array of invoice PDF in code-behind. Web interface should be as below :

User Input Data
First, we download the "itextsharp.dll" and add reference at web site as below:
We need the following namespace in web page as below:
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using System.Data;
Copy the following code into form tag for interface :
<form id="form1" runat="server">
<div>
    <asp:Label ID="Label1" runat="server" Text="Order No :" Width="120px"></asp:Label>
    <asp:TextBox ID="txtOrderNo" runat="server"></asp:TextBox><br/>
    <asp:Label ID="Label2" runat="server" Text="Customer Name :" Width="120px"></asp:Label>
    <asp:TextBox ID="txtCustomerName" runat="server">John Willion</asp:TextBox><br />
    <asp:Label ID="Label3" runat="server" Text="Address :" Width="120px"></asp:Label>
    <asp:TextBox ID="txtAddress" runat="server" Height="74px" TextMode="MultiLine" Width="249px">No. 123, New Panasin Street, Ramkhamkeang 24/1, Bangkapi, Bangkok, 10200.</asp:TextBox>
</div>
<div>
    <asp:RadioButton ID="rdoDownload" runat="server" Checked="True" GroupName="pdf" Text="Download PDF" />
    <asp:RadioButton ID="rdoSendEmail" runat="server" GroupName="pdf" Text="Send PDF with email" />
</div>
<div>
    <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" Font-Names="Arial"
        Font-Size="11pt" AlternatingRowStyle-BackColor="#C2D69B" HeaderStyle-BackColor="green"
        AllowPaging="true" PageSize="10" OnPageIndexChanging="GridView1_PageIndexChanging">
        <Columns>
            <asp:BoundField ItemStyle-Width="150px" DataField="NO" HeaderText="NO" />
            <asp:BoundField ItemStyle-Width="150px" DataField="ITEM" HeaderText="ITEM" />
            <asp:BoundField ItemStyle-Width="150px" DataField="QUANTITY" HeaderText="QUANTITY" />
            <asp:BoundField ItemStyle-Width="150px" DataField="AMOUNT" HeaderText="AMOUNT(IDR)" />
        </Columns>
    </asp:GridView>
</div>
<div>
    <asp:Button ID="Button1" runat="server" Text="Create PDF" OnClick="Button1_Click" />
</div>
</form>

Copy the following code to code-behind for class variables and data binding for gridview :
//Class Variables
string orderNo = DateTime.Now.Ticks.ToString().Substring(0, 6);
string orderDate = DateTime.Now.ToString("dd MMM yyyy");
decimal totalAmtStr;
string accountNo = "0123456789012";
string accountName = "John Willion";
string branch = "Phahon Yothin Branch";
string bank = "Kasikorn Bank";

// for Gridview
DataTable dt = new DataTable();

protected void Page_Load(object sender, EventArgs e)
{
    //This sample used iTextShart.dll - 4.1.6.0
    // DataTable binding
    txtOrderNo.Text = orderNo;
    dt.Columns.Add("NO", Type.GetType("System.String"));
    dt.Columns.Add("ITEM", Type.GetType("System.String"));
    dt.Columns.Add("QUANTITY", Type.GetType("System.String"));
    dt.Columns.Add("AMOUNT", Type.GetType("System.String"));

    for (int i = 0; i < 10; ++i)
    {
        dt.Rows.Add();
        dt.Rows[i]["NO"] = (i + 1).ToString();
        dt.Rows[i]["ITEM"] = "Item " + i.ToString();
        dt.Rows[i]["QUANTITY"] = (i + 1).ToString();
        dt.Rows[i]["AMOUNT"] = (i + 1).ToString();
        totalAmtStr += (i + 1);
    }

    //GridView 
    GridView1.DataSource = dt;
    GridView1.DataBind();
}
Let's create "CreatePDF()" function in code-behind as below:
protected MemoryStream CreatePDF()
{
    // Create a Document object
    Document document = new Document(PageSize.A4, 70, 70, 70, 70);

    //MemoryStream
    MemoryStream PDFData = new MemoryStream();
    PdfWriter writer = PdfWriter.GetInstance(document, PDFData);

    // First, create our fonts
    var titleFont = FontFactory.GetFont("Arial", 14, Font.BOLD);
    var boldTableFont = FontFactory.GetFont("Arial", 10, Font.BOLD);
    var bodyFont = FontFactory.GetFont("Arial", 10, Font.NORMAL);
    Rectangle pageSize = writer.PageSize;

    // Open the Document for writing
    document.Open();
    //Add elements to the document here

    #region Top table
    // Create the header table 
    PdfPTable headertable = new PdfPTable(3);
    headertable.HorizontalAlignment = 0;
    headertable.WidthPercentage = 100;
    headertable.SetWidths(new float[] { 4, 2, 4 });  // then set the column's __relative__ widths
    headertable.DefaultCell.Border = Rectangle.NO_BORDER;
    //headertable.DefaultCell.Border = Rectangle.BOX; //for testing
    headertable.SpacingAfter = 30;
    PdfPTable nested = new PdfPTable(1);
    nested.DefaultCell.Border = Rectangle.BOX;
    PdfPCell nextPostCell1 = new PdfPCell(new Phrase("ABC Co.,Ltd", bodyFont));
    nextPostCell1.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
    nested.AddCell(nextPostCell1);
    PdfPCell nextPostCell2 = new PdfPCell(new Phrase("111/206 Moo 9, Ramkhamheang Road,", bodyFont));
    nextPostCell2.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
    nested.AddCell(nextPostCell2);
    PdfPCell nextPostCell3 = new PdfPCell(new Phrase("Nonthaburi 11120", bodyFont));
    nextPostCell3.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
    nested.AddCell(nextPostCell3);
    PdfPCell nesthousing = new PdfPCell(nested);
    nesthousing.Rowspan = 4;
    nesthousing.Padding = 0f;
    headertable.AddCell(nesthousing);

    headertable.AddCell("");
    PdfPCell invoiceCell = new PdfPCell(new Phrase("INVOICE", titleFont));
    invoiceCell.HorizontalAlignment = 2;
    invoiceCell.Border = Rectangle.NO_BORDER;
    headertable.AddCell(invoiceCell);
    PdfPCell noCell = new PdfPCell(new Phrase("No :", bodyFont));
    noCell.HorizontalAlignment = 2;
    noCell.Border = Rectangle.NO_BORDER;
    headertable.AddCell(noCell);
    headertable.AddCell(new Phrase(orderNo, bodyFont));
    PdfPCell dateCell = new PdfPCell(new Phrase("Date :", bodyFont));
    dateCell.HorizontalAlignment = 2;
    dateCell.Border = Rectangle.NO_BORDER;
    headertable.AddCell(dateCell);
    headertable.AddCell(new Phrase(orderDate, bodyFont));
    PdfPCell billCell = new PdfPCell(new Phrase("Bill To :", bodyFont));
    billCell.HorizontalAlignment = 2;
    billCell.Border = Rectangle.NO_BORDER;
    headertable.AddCell(billCell);
    headertable.AddCell(new Phrase(txtCustomerName.Text + "\n" + txtAddress.Text, bodyFont));
    document.Add(headertable);
    #endregion

    #region Items Table
    //Create body table
    PdfPTable itemTable = new PdfPTable(4);
    itemTable.HorizontalAlignment = 0;
    itemTable.WidthPercentage = 100;
    itemTable.SetWidths(new float[] { 10, 40, 20, 30 });  // then set the column's __relative__ widths
    itemTable.SpacingAfter = 40;
    itemTable.DefaultCell.Border = Rectangle.BOX;
    PdfPCell cell1 = new PdfPCell(new Phrase("NO", boldTableFont));
    cell1.HorizontalAlignment = 1;
    itemTable.AddCell(cell1);
    PdfPCell cell2 = new PdfPCell(new Phrase("ITEM", boldTableFont));
    cell2.HorizontalAlignment = 1;
    itemTable.AddCell(cell2);
    PdfPCell cell3 = new PdfPCell(new Phrase("QUANTITY", boldTableFont));
    cell3.HorizontalAlignment = 1;
    itemTable.AddCell(cell3);
    PdfPCell cell4 = new PdfPCell(new Phrase("AMOUNT(USD)", boldTableFont));
    cell4.HorizontalAlignment = 1;
    itemTable.AddCell(cell4);

    foreach (DataRow row in dt.Rows)
    {
        PdfPCell numberCell = new PdfPCell(new Phrase(row["NO"].ToString(), bodyFont));
        numberCell.HorizontalAlignment = 0;
        numberCell.PaddingLeft = 10f;
        numberCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
        itemTable.AddCell(numberCell);

        PdfPCell descCell = new PdfPCell(new Phrase(row["ITEM"].ToString(), bodyFont));
        descCell.HorizontalAlignment = 0;
        descCell.PaddingLeft = 10f;
        descCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
        itemTable.AddCell(descCell);

        PdfPCell qtyCell = new PdfPCell(new Phrase(row["QUANTITY"].ToString(), bodyFont));
        qtyCell.HorizontalAlignment = 0;
        qtyCell.PaddingLeft = 10f;
        qtyCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
        itemTable.AddCell(qtyCell);

        PdfPCell amtCell = new PdfPCell(new Phrase(row["AMOUNT"].ToString(), bodyFont));
        amtCell.HorizontalAlignment = 1;
        amtCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER;
        itemTable.AddCell(amtCell);

    }
    // Table footer
    PdfPCell totalAmtCell1 = new PdfPCell(new Phrase(""));
    totalAmtCell1.Border = Rectangle.LEFT_BORDER | Rectangle.TOP_BORDER;
    itemTable.AddCell(totalAmtCell1);
    PdfPCell totalAmtCell2 = new PdfPCell(new Phrase(""));
    totalAmtCell2.Border = Rectangle.TOP_BORDER; //Rectangle.NO_BORDER; //Rectangle.TOP_BORDER;
    itemTable.AddCell(totalAmtCell2);
    PdfPCell totalAmtStrCell = new PdfPCell(new Phrase("Total Amount", boldTableFont));
    totalAmtStrCell.Border = Rectangle.TOP_BORDER;   //Rectangle.NO_BORDER; //Rectangle.TOP_BORDER;
    totalAmtStrCell.HorizontalAlignment = 1;
    itemTable.AddCell(totalAmtStrCell);
    PdfPCell totalAmtCell = new PdfPCell(new Phrase(totalAmtStr.ToString("#,###.00"), boldTableFont));
    totalAmtCell.HorizontalAlignment = 1;
    itemTable.AddCell(totalAmtCell);

    PdfPCell cell = new PdfPCell(new Phrase("*** Please note that ABC Co., Ltd’s bank account is USD Bank Account ***", bodyFont));
    cell.Colspan = 4;
    cell.HorizontalAlignment = 1;
    itemTable.AddCell(cell);
    document.Add(itemTable);
    #endregion

    Chunk transferBank = new Chunk("Your Bank Account:", boldTableFont);
    transferBank.SetUnderline(0.1f, -2f); //0.1 thick, -2 y-location
    document.Add(transferBank);
    document.Add(Chunk.NEWLINE);

    // Bank Account Info
    PdfPTable bottomTable = new PdfPTable(3);
    bottomTable.HorizontalAlignment = 0;
    bottomTable.TotalWidth = 300f;
    bottomTable.SetWidths(new int[] { 90, 10, 200 });
    bottomTable.LockedWidth = true;
    bottomTable.SpacingBefore = 20;
    bottomTable.DefaultCell.Border = Rectangle.NO_BORDER;
    bottomTable.AddCell(new Phrase("Account No", bodyFont));
    bottomTable.AddCell(":");
    bottomTable.AddCell(new Phrase(accountNo, bodyFont));
    bottomTable.AddCell(new Phrase("Account Name", bodyFont));
    bottomTable.AddCell(":");
    bottomTable.AddCell(new Phrase(accountName, bodyFont));
    bottomTable.AddCell(new Phrase("Branch", bodyFont));
    bottomTable.AddCell(":");
    bottomTable.AddCell(new Phrase(branch, bodyFont));
    bottomTable.AddCell(new Phrase("Bank", bodyFont));
    bottomTable.AddCell(":");
    bottomTable.AddCell(new Phrase(bank, bodyFont));
    document.Add(bottomTable);

    //Approved by
    PdfContentByte cb = new PdfContentByte(writer);
    BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, true);
    cb = writer.DirectContent;
    cb.BeginText();
    cb.SetFontAndSize(bf, 10);
    cb.SetTextMatrix(pageSize.GetLeft(300), 200);
    cb.ShowText("Approved by,");
    cb.EndText();
    //Image Singature
    iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance(Server.MapPath("~/Images/Bill_Gates2.png"));
    logo.SetAbsolutePosition(pageSize.GetLeft(300), 140);
    document.Add(logo);

    cb = new PdfContentByte(writer);
    bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, true);
    cb = writer.DirectContent;
    cb.BeginText();
    cb.SetFontAndSize(bf, 10);
    cb.SetTextMatrix(pageSize.GetLeft(70), 100);
    cb.ShowText("Thank you for your business! If you have any questions about your order, please contact us at 800-555-NORTH.");
    cb.EndText();

    writer.CloseStream = false; //set the closestream property
    // Close the Document without closing the underlying stream
    document.Close();
    return PDFData;
}
Copy the following function to code-behind for downloading the Invoice PDF:
protected void DownloadPDF(System.IO.MemoryStream PDFData)
{
    // Clear response content & headers
    Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    Response.ContentType = "application/pdf";
    Response.Charset = string.Empty;
    Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
    Response.AddHeader("Content-Disposition", string.Format("attachment;filename=Receipt-{0}.pdf", orderNo));
    Response.OutputStream.Write(PDFData.GetBuffer(), 0, PDFData.GetBuffer().Length);
    Response.OutputStream.Flush();
    Response.OutputStream.Close();
    Response.End();
}
Finally, copy the following code into "Button1_Click" :
protected void Button1_Click(object sender, EventArgs e)
{
    if (rdoDownload.Checked)
    {
        DownloadPDF(CreatePDF());
    }
    else
    {
        MemoryStream ms = CreatePDF();
        ms.Position = 0; //Set pointer to the beginning of the stream
        byte[] PDFData = new byte[ms.Length];
        ms.Read(PDFData, 0, (int)ms.Length); // get byte arrary for PDF 
       // Attach byte array to email here
    }
}

Hope this helps,
SI THU

Reference :
http://www.4guysfromrolla.com/articles/030911-1.aspx
http://www.mikesdotnetting.com/Article/86/iTextSharp-Introducing-Tables

Sunday, September 15, 2013

How to create link button and event handler programmatically in user control

We often have the scenario that it need to generate LinkButtons in our web application depend on user role or action. This post explain you step by step how to create link buttons and their event handler dramatically in user control and use in .aspx page as below image :
Dynamic link buttons
First, create one user control ("LinkButtonControl.ascx") and copy the following code to that control. It uses PlaceHolder contron that is to store dynamically added server controls on the Web page.
<fieldset style="width: 200px;">
    <legend>Dynamic Links</legend>
    <ul>
        <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
    </ul>
</fieldset>
In code-behind, it should look like as below :
public partial class LinkButtonControl : System.Web.UI.UserControl
{
    //Declare event handler 
    public delegate void LinkButtonEventHandler(object sender, EventArgs e);
    public event LinkButtonEventHandler LinkButtonClick;
    //Create generic list object 
    List<LinkControl> linkControlList = new List<LinkControl>();

    protected void Page_Load(object sender, EventArgs e)
    {
        //Add the sample data to generic list
        linkControlList.Add(new LinkControl { Name = "aboutus", Title = "About Us", Url = "aboutus.aspx" });
        linkControlList.Add(new LinkControl { Name = "contactus", Title = "Contact Us", Url = "contactus.aspx" });
        linkControlList.Add(new LinkControl { Name = "tou", Title = "Term of use", Url = "TOU.aspx" });
        CreateLinkButtons();
    }
    public void CreateLinkButtons()
    {
        foreach (var link in linkControlList)
        {
            //Create LinkButton programmatically 
            LinkButton lb = new LinkButton();
            lb.ID = link.Name;
            lb.Text = link.Title;
            lb.CommandArgument = link.Url;
            lb.Click += new EventHandler(this.LinkButtonClick);
            //Add LinkButton to PlaceHolder
            PlaceHolder1.Controls.Add(new LiteralControl(@"<li>"));
            PlaceHolder1.Controls.Add(lb);
            PlaceHolder1.Controls.Add(new LiteralControl(@"</li>"));
        }
    }
    protected void LinkButton_Click(object sender, EventArgs e)
    {
        if (LinkButtonClick != null)
            LinkButtonClick(sender, e);
    }
}
//Data Transfer Object class  
public class LinkControl
{
    public string Name{get; set; }
    public string Title { get; set; }
    public string Url { get; set; }
}
Second, create one .aspx page("UserControlTest.aspx") and add the follow CSS to <head> tag for link button layout.
<style type="text/css">
    ul 
    {
        list-style-type: none;
        margin: 0;
        padding: 0;
    }
</style>
Finally, drag and drop our user control ("LinkButtonControl.ascx") to .aspx page and add "OnLinkButtonClick" event manually as below :
<uc1:LinkButtonControl ID="LinkButtonControl1" runat="server" OnLinkButtonClick="LinkButtonControl1_Click" />    
Copy the following code snippet to code-behind for event implementation.   
protected void LinkButtonControl1_Click(object sender, EventArgs e)
{
    LinkButton lb = sender as LinkButton;
    if (lb != null)
        Response.Redirect(lb.CommandArgument);
}
That's it.

Hope this helps
SI THU WIN

Sunday, July 21, 2013

How to create and read Xml in asp.net

We often have to deal with Xml message when our applications are integrated with SMS Api, Email Api or Payment Api. At that time, we prepare Xml message and feed the services. Likewise, it gets the Xml message from the service of API and extracts the message from Xml message for on-going process. This post explain step by step how to create Xml message and read the message from Xml elements.

First, copy and paste the following Xml message to new file "XmlMessage.xml" in "App_Data" folder in your project. You see "[xxxxxxx]" and it is place holder for data we put.
<?xml version="1.0" encoding="utf-8" ?>
<paymentService version="1.4" merchantCode="[merchantCode]">
  <reply>
    <orderStatus orderCode="[orderCode]">
      <payment>
        <paymentMethod>[paymentMethod]</paymentMethod>
        <amount value="[value]" currencyCode="[currencyCode]" exponent="[exponent]"/>
        <lastEvent>[lastEvent]</lastEvent>
        <CVCResultCode description="[CVCResultCode]"/>
        <ISO8583ReturnCode code="[ISO8583ReturnCode]" description="[ISO8583ReturnDescription]"/>
      </payment>
    </orderStatus>
  </reply>
</paymentService>
Second, we need to add Textbox server control to .aspx page as below:
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TextBox ID="txtXml" runat="server" Height="250px" Width="576px" 
            TextMode="MultiLine"></asp:TextBox>
    </div>
    </form>
</body>
Third, copy and paste the following code in code behind.
protected void Page_Load(object sender, EventArgs e)
{
    //Set the data here.
    string merchantCode = "MYMERCHANT";
    string orderCode = "T0211234";
    string paymentMethod = "ECMC-SSL";
    string value = "162095";
    string currencyCode = "GPB";
    string exponent = "2";
    string lastEvent = "REFUSED";
    string CVCResultCode = "NOT SUPPLIED BY SHOPPER";
    string ISO8583ReturnCode = "33";
    string ISO8583ReturnDescription = "CARD EXPIRED";

    string xmlMsg = GetXmlMessage();
    //Fill the data in place holder in Xml message.
    xmlMsg = xmlMsg.Replace("[merchantCode]", merchantCode);
    xmlMsg = xmlMsg.Replace("[orderCode]", orderCode);
    xmlMsg = xmlMsg.Replace("[paymentMethod]", paymentMethod);
    xmlMsg = xmlMsg.Replace("[value]", value);
    xmlMsg = xmlMsg.Replace("[currencyCode]", currencyCode);
    xmlMsg = xmlMsg.Replace("[exponent]", exponent);
    xmlMsg = xmlMsg.Replace("[lastEvent]", lastEvent);
    xmlMsg = xmlMsg.Replace("[CVCResultCode]", CVCResultCode);
    xmlMsg = xmlMsg.Replace("[ISO8583ReturnCode]", ISO8583ReturnCode);
    xmlMsg = xmlMsg.Replace("[ISO8583ReturnDescription]", ISO8583ReturnDescription);
    txtXml.Text = xmlMsg;
    ReadXmlMessage(xmlMsg);
}

public string GetXmlMessage()
{
    //Get Xml message from file.
    string XmlFile = "~/App_Data/XmlMessage.xml";
    StreamReader sr = new StreamReader(Server.MapPath(XmlFile));
    string str = sr.ReadToEnd();
    return str;
}

public void ReadXmlMessage(string xmlMsg)
{
    if (!string.IsNullOrEmpty(xmlMsg))
    {
        //Read the data from Xml elements.
        XmlDocument document = new XmlDocument();
        document.LoadXml(xmlMsg);
        string merchantCode = document.GetElementsByTagName("paymentService")[0].Attributes["merchantCode"].Value;
        string orderCode = document.GetElementsByTagName("orderStatus")[0].Attributes["orderCode"].Value;
        string paymentMethod = document.SelectSingleNode("//paymentMethod").InnerText;
        string value = document.GetElementsByTagName("amount")[0].Attributes["value"].Value;
        string currencyCode = document.GetElementsByTagName("amount")[0].Attributes["currencyCode"].Value;
        string exponent = document.GetElementsByTagName("amount")[0].Attributes["exponent"].Value;
        string lastEvent = document.SelectSingleNode("//lastEvent").InnerText;
        string CVCResultCode = document.GetElementsByTagName("CVCResultCode")[0].Attributes["description"].Value;
        string ISO8583ReturnCode = document.SelectSingleNode("//ISO8583ReturnCode").Attributes["code"].Value;
        string ISO8583ReturnDescription = document.SelectSingleNode("//ISO8583ReturnCode").Attributes["description"].Value;
    }
}
I use XmlNode.SelectSingleNode method to get xml data. It selects the first XmlNode that matches the XPath expression. The first XmlNode that matches the XPath query or null if no matching node is found.
I used aslo XmlDocument.GetElementsByTagName method to return an XmlNodeList containing a list of all descendant elements that match the specified Name. If no nodes match name, the returned collection will be empty.

Finally, run and see the result. It look like as below: