Background
When working in ASP.NET, we will be facing requirement to have communication between server and client frequently. For Example, let us consider the below use case.
The requirement is to have a Web page for Customer invoicing. When the user rising invoice, the application should verify as defined below.
- Get the Customer ID and Invoice Amount from Web Page
- When the user press Save button, the application required to get the existing outstanding amount and allowed outstanding amount for that customer.
- When invoice amount + existing outstanding amount is more then allowed outstanding amount then inform the user the amount is exceeded with Proceed and Cancel button.
- When the user press Proceed button, it should call the server event for invoicing.
- When the user press Cancel button, it won’t proceed.
- When invoice amount + existing outstanding amount is lesser then allowed outstanding amount then call the server event for invoicing.
If the outstanding amount is exceeding, it will get the user confirmation to continue further process. When user confirm the proceed signal it will proceed as usual and if not it won’t.
The below diagram will be useful for understanding the same –
Implementation
For keeping customer details, I have defined two XML file in the project.
- CustomerTypes.xml
The Customer type xml file holds information about customer types. Currently I have three types such as A, B, C. Each customer type have different allowable outstanding amount.
<?xml version="1.0" encoding="utf-8" ?> <CustomerTypes> <CustomerType> <Id>A</Id> <AllowedOutstadingAmount>25000</AllowedOutstadingAmount> </CustomerType> <CustomerType> <Id>B</Id> <AllowedOutstadingAmount>15000</AllowedOutstadingAmount> </CustomerType> <CustomerType> <Id>C</Id> <AllowedOutstadingAmount>12000</AllowedOutstadingAmount> </CustomerType> </CustomerTypes>
- Customers.xml
The Customer xml holds information about customer. Each customer has properties such as Id, Name, Customer Type, Current outstanding amount and Customer Type.
<?xml version="1.0" encoding="utf-8" ?> <Customers> <Customer> <Id>ALFKI</Id> <Name>Alfreds Futterkiste</Name> <Phone>030-0074321</Phone> <OutstadingAmount>23000</OutstadingAmount> <CustomerType>A</CustomerType> </Customer> <Customer> <Id>ANATR</Id> <Name>Ana Trujillo Emparedados y helados</Name> <Phone>(5) 555-4729</Phone> <OutstadingAmount>15000</OutstadingAmount> <CustomerType>B</CustomerType> </Customer> <Customer> <Id>ANTON</Id> <Name>Antonio Moreno Taquería</Name> <Phone>(5) 555-3932</Phone> <OutstadingAmount>10000</OutstadingAmount> <CustomerType>C</CustomerType> </Customer> </Customers>
Below is the aspx script for defining user interface (Default.aspx).
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent"> <%--This div control can also place in Master Page, so it can be used for all pages--%> <div id="divHidden"> </div> <div id="progrssShow"> <p style="text-align:center;font-size:20px;color:Red;font-weight:bold;">Please wait.</p> <p style="text-align:center;font-size:15px;">Request is being created.... </p> </div> <div id="confirmShow"> <p id="Message"></p> <div style="text-align:center"> <input id="Proceed" value="Proceed" type="button" class="Proceed" /> <input id="Cancel" value="Cancel" type="button" class="Cancel" /> </div> </div> <table> <tr><td colspan="2">New Invoice</td></tr> <tr> <td>Customer ID</td> <td><asp:TextBox runat="server" ID="txtCustomerID" CssClass="CustomerID" Width="120px" Text=""></asp:TextBox></td> </tr> <tr> <td>Invoice Amount</td> <td><asp:TextBox runat="server" ID="txtInvoiceAmount" CssClass="InvoiceAmount" Width="80px" Text=""></asp:TextBox></td> </tr> <tr> <td colspan="2" style="text-align:center"> <asp:Button ID="btnServerSave" CssClass="btnServerSave" Text="Server Save" runat="server" onclick="btnServerSave_Click" /> <input id="btnSave2" class="btnSave" value="Save" type="button" /> </td> </tr> </table> <asp:Label runat="server" ID="lblMessage" Text=""></asp:Label> </asp:Content>
The User Interface at initial stage will be as bellow
There are three additional div controls are used in the aspx script for giving better usability.
1. divHidden
When pressing Save button, the divHidden div control is used to make the page inactive (the control on the screen will not be usable). The style sheet for the divHidden control defined an image as background and z-index to top.
2. progrssShow
This control is used to show information to the user "Please Wait. Request is being created...." when the application verifying the outstanding amount exceeded. (I use Thread.Sleep(1000) to see the information, if required it can be removed)
The screen layout will be
3. confirmShow
This is again a popup control for getting confirmation from the user to proceed or not. This control also will show the current and allowed outstanding amount.
The screen layout will be
The code behind Default.aspx.cs
protected void btnServerSave_Click(object sender, EventArgs e) { lblMessage.Text = "Server Event called"; }I have the added below Style Sheet
/* Added Newly */ #divHidden { width: 100%; height:100%; background-color:Gray; background: url(../Images/hidden.png) repeat; position: absolute; top: 0; left: 0; z-index: 100; display: none; } #progrssShow { width: 460px; height: 120px; background-color: White; position: absolute; left: 45%; top: 45%; margin-top: -50px; margin-left: -168px; vertical-align:middle; z-index: 1001; display: none; } .btnServerSave { display:none; } #confirmShow { width: 550px; height: 220px; background-color: White; position: absolute; left: 40%; top: 40%; margin-top: -50px; margin-left: -168px; vertical-align:middle; z-index: 1001; display: none; } #progrssShow P, #confirmShow P { width: 85%; margin: 10px auto; text-align: left; } #progrssShow P.button #confirmShow P.button { padding-top: 10px; border-top: 1px solid #D1D1D1; }I am using a Generic Handler for getting customer information such as current outstanding amount, allowed outstanding amount.
public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; string retValue = string.Empty; try { // For delaying the process System.Threading.Thread.Sleep(1000); if (context.Request.Form["CustomerID"] != null) { // Get the Customer ID string strCustomerID = context.Request.Form["CustomerID"]; // Get the Customer string strCustomerFileName = context.Request.PhysicalApplicationPath + @"Data\Customers.xml"; if (File.Exists(strCustomerFileName)) { double dblOutstandingAmount = 0; string strCustomerType = string.Empty; double dblAllowedOutstandingAmount = 0; // Getting the existing outstanding amount and Customer Type XPathDocument doc = new XPathDocument(strCustomerFileName); XPathNavigator nav = doc.CreateNavigator(); XPathNodeIterator iterator = nav.Select("//Customer[Id = '" + strCustomerID + "']"); while (iterator.MoveNext()) { XPathNavigator nav2 = iterator.Current.Clone(); dblOutstandingAmount = Convert.ToDouble(nav2.Select("Customer").Current.SelectSingleNode("OutstadingAmount").InnerXml); strCustomerType = nav2.Select("Customer").Current.SelectSingleNode("CustomerType").InnerXml; } // Getting the allowed Outstanding Amount string strCustomerTypeFileName = context.Request.PhysicalApplicationPath + @"Data\CustomerTypes.xml"; if (File.Exists(strCustomerTypeFileName)) { doc = new XPathDocument(strCustomerTypeFileName); nav = doc.CreateNavigator(); iterator = nav.Select("//CustomerType[Id = '" + strCustomerType + "']"); while (iterator.MoveNext()) { XPathNavigator nav2 = iterator.Current.Clone(); dblAllowedOutstandingAmount = Convert.ToDouble(nav2.Select("CustomerType").Current.SelectSingleNode("AllowedOutstadingAmount").InnerXml); } // Now the business logic to decide is it allowed. bool IsProceed = false; if ((dblOutstandingAmount + Convert.ToDouble(context.Request.Form["InvoiceAmount"].ToString())) <= dblAllowedOutstandingAmount) IsProceed = true; //We can even write as JSON object. But as we dont have any complex data structure we are using comma (,) only for separating the data values. string[] values = new string[] { "successful", strCustomerID.ToString(), strCustomerType.ToString(), IsProceed.ToString(), dblOutstandingAmount.ToString(), dblAllowedOutstandingAmount.ToString() }; // JSON Serialize the array System.Web.Script.Serialization.JavaScriptSerializer objSerializer = new System.Web.Script.Serialization.JavaScriptSerializer(); retValue = objSerializer.Serialize(values); } else retValue = "unsuccessful"; } else retValue = "unsuccessful"; } else retValue = "unsuccessful"; } catch { retValue = "unsuccessful"; } context.Response.Write(retValue); }This code returns a JSON string which has "Successful" message, Customer Id, Customer Type, Whether to Proceed, Current Outstanding Amount, Allowed Outstanding Amount.
Note: I use XML files to simplify the implementation instead of using a database. The main reason of this post is to understand the client and server conversations and to get the user inputs between two server events.
Finally the JQuery for handing all the UI functionality defined below
$(document).ready(function () { // This function is for cancel button, when click of this button the popup screen will be hidden and show as normal. $(".Cancel").click(function () { $("#confirmShow").css("display", "none"); $("#divHidden").css("display", "none"); }); // This function is called whe Proceed button clicked, and it calls the server event. $(".Proceed").click(function () { $(".btnServerSave").click(); }); // This function is called when clicking Save button. $(".btnSave").click(function (event) { if (($(".CustomerID").val().length == 0) || ($(".InvoiceAmount").val().length == 0)) { alert("Enter Customer Id and Invoice Amount for proceeding further"); event.preventDefault(); } else { $("#divHidden").css("display", "block"); $("#progrssShow").css("display", "block"); jQuery.post('CustomerHandler.ashx', { CustomerID: $(".CustomerID").val(), InvoiceAmount: $(".InvoiceAmount").val() }, function (data) { var ArrValue = eval(data); // Convert the JSON object as array if (ArrValue[0] != "unsuccessful") { if (data == "NotExist") { alert('There is something gone wrong. Please contact Administrator.'); $("#divHidden").css("display", "block"); $("#progrssShow").css("display", "none"); return false; } else if (ArrValue[0] == 'successful') { if (ArrValue[3] == "False") { $("#progrssShow").css("display", "none"); $("#confirmShow").css("display", "block"); var msg = "<b style='color:red; padding-left:40%'>Alert!!!</b>" + "The invoice amount exceeded the allowed outstanding amount!!!. " + "Outstanding Amount : " + ArrValue[4] + "Allowed Outstanding Amount : " + ArrValue[5] + "Do you want to proceed..."; $("#Message").html(msg); } else { $(".btnServerSave").click(); } } else { return true; // Will not happen as per handler } } else { alert('There is something gone wrong. Please contact Administrator.'); return false; } } ); } }); });
Below is the video
Download the working source code in C# here and in VB here.
Love the post, especially the video at the bottom. Thanks for the source code.
Thanks Moderator...
Very useful informations about these subject. I have found them with googling and you seems on the top of these subjects !
Thanks Ricky Martin...
Very useful information about these subject. Thanks for sharing
Roatan fishing
Good stuff. It is interesting to read comments.