Wednesday, April 13, 2011

Caching in Asp.net

 

Caching

This article, you will learn about concepts, advantages, types of caching and about implementation of caching in ASP.NET applications. The code also serves as an example of using inline coding, creating user controls, trace mechanism, etc.


What is Caching?

 

Caching is a technique of persisting the data in memory for immediate access to requesting program calls. Many in the developer community consider caching as one of the features available to improve performance of Web applications.


Why Caching?

Consider a page that has list of Employee name, contact numbers and mail-Ids of existing employees of a company on an intranet accessible by all employees. This is very useful information that is available throughout the company and could also be one of the most accessed pages. The functionality of adding, updating or deleting is usually less intensive compared to more transaction-based systems like Purchase ordering, Voucher creation etc. Now in a normal scenario the process of querying database for each request is not cost-effective in terms of server resources, hence is lot better to cache or persist the data to avoid this costly loss of resources.

The .NET Advantage

 ASP.NET provides the flexibility in terms of caching at different levels.


1. Page Level Output Caching


This is at the page level and one of the easiest means for caching pages. This requires one to specify Duration of cache and Attribute of caching.

Syntax: <%@ OutputCache Duration="60" VaryByParam="none" %> 





The above syntax specifies that the page be cached for duration of 60 seconds and the value "none" for VaryByParam* attribute makes sure that there is a single cached page available for this duration specified.

* VaryByParam can take various "key" parameter names in query string. Also there are other attributes like VaryByHeader, VaryByCustom etc. Please refer to MSDN for more on this.





2. Fragment Caching





Even though this definition refers to caching portion/s of page, it is actually caching a user control that can be used in a base web form page. In theory, if you have used include files in the traditional ASP model then this caching model is like caching these include files separately. In ASP.NET more often this is done through User Controls. Initially even though one feels a bit misleading, this is a significant technique that can be used especially when implementing "n" instances of the controls in various *.aspx pages. We can use the same syntax that we declared for the page level caching as shown above, but the power of fragment caching comes from the attribute "VaryByControl". Using this attribute one can cache a user control based on the properties exposed.






Syntax: <%@ OutputCache Duration="60" VaryByControl="DepartmentId" %>







The above syntax when declared within an *.ascx file ensures that the control is cached for 60 seconds and the number of representations of cached control is dependant on the property "DepartmentId" declared in the control.

Add the following into an *.ascx file. Please note the use of tag "Control" and the cache declaration.






<%@ Control Language="C#"%> 



<%@ outputcache duration="60" varybycontrol="DepartMentId" %> 



<script runat="server">
   1:  
   2: private int _Departmentid=0; 
   3: public int DepartMentId 
   4: { 
   5: get{return _Departmentid;} 
   6: set{_Departmentid =value;} 
   7: } 
   8: //Load event of control 
   9: void Page_Load(Object sender, EventArgs e) 
  10: { 
  11: lblText.Text = "Time is " + DateTime.Now.ToString() + " for Department id = " 
  12: + _Departmentid + "\n"; 
  13: } 
</script>



<asp:Label id="lblText" runat="server"></asp:Label> 




Add the following to an *.aspx file. Please note the way "Register" tag is used; the declaration of control using syntax <[TagPrefix]:[TagName]>; Usage of property " DepartMentId". Open the page in two browsers and closely watch the Base form timing and the User control timing. Also note that the following page results in two copies or representation of user control in the cache.






<%@ Page Language="C#" Trace="true" %> 



<%@ Register TagPrefix="CacheSample" TagName="Text" Src="CachingControl.ascx" %> 



<script runat=server>
   1:  
   2: void Page_Load(Object sender, EventArgs e) 
   3: { 
   4: this.lbltime.Text ="Base form time is " + DateTime.Now.ToString() + "\n"; 
   5: } 
</script>



<html> 



<head> 



</head> 



<body> 



<form runat="server" ID="Form2"> 



<table> 



<tbody> 



<tr> 



<td> 



<asp:Label id="lbltime" runat="server"></asp:Label> 



</td> 



</tr> 



<tr> 



<td> 



<CACHESAMPLE:TEXT id="instance1" runat="Server" DepartMentId="0"> 



</CACHESAMPLE:TEXT> 



</td> 



</tr> 



<tr> 



<td> 



<CACHESAMPLE:TEXT id="instance2" runat="Server" DepartMentId="1"> 



</CACHESAMPLE:TEXT> 



</td> 



</tr> 



</tbody> 



</table> 



</form> 



</body> 



</html> 





3. Application Level Caching






With Page level Output caching one cannot cache objects between pages within an application. Fragment caching is great in that sense but has limitations by using user controls as means to do. We can use the Cache object programmatically to take advantage of caching objects and share the same between pages. Further the availability of different overloaded methods gives a greater flexibility for our Cache policy like Timespan, Absolute expiration etc. But one of the biggest takes is the CacheDependancy. This means that one can create a cache and associate with it a dependency that is either another cache key or a file.

In almost all Web applications there could be numerous master tables that act as lookups to application specific tables. For e.g. if you take up adding a Employee, usually one has master tables like "tblQualification" to get list of qualifications, "tblLocations" to get list of locations etc. These tables* are usually set during the initial application configuration phase and could be modified once a month or even less than that. Hence it makes sense for us to use them in our Cache rather than making calls to database on each request. But then what Cache Policy do we adopt?


We cannot hold these objects in Cache for entire application instance, because if anybody changes data in these tables one has to also refresh the cache. It is here that CacheDependancy can be used.


* Even though these tables are less frequently used for updates, they are extensively used in our select statements through out the applications.


Find below the snippet that uses CacheDependancy. Here what I have done is to provide a list view of existing employees. You need to create a Database in Sql Server, setup some data before you can continue. The schema scripts are enclosed in the article.


Add database connection value in Web.Config and change the value as per your setup.






<appSettings> 



<add key="conn" value="Data Source=vishnu;trusted_connection=yes;Initial Catalog=Users"/> 



</appSettings> 




First I get the dataset into which I fill the user list. But before this I check for the cache initially if it exists I directly cast it to a dataset, if not create a cache again.

daUsers.Fill(dsUsers,"tblUsers");


I create the cache with "Users" as key using Cache.Insert* and link this with a file "Master.xml". This "Master.xml" is a XML file that contains Master data of "tblQualifications" and "tbllocations". I have used "Server.MapPath" to get the physical path of the file on the server. The CacheDependancy instance will make sure that any change in this dependency file means that you need to recreate your cache key definition. This is a great feature to use since I can recreate my cache only when required instead of caching the data at the page level
.







* For other overloaded parameters refer MSDN.Also note how we could use trace within to add my own statements.



 



Cache.Insert("Users",dsUsers,new System.Web.Caching.CacheDependency(Server.MapPath("Master.xml")) , DateTime.Now.AddSeconds(45),TimeSpan.Zero); 



HttpContext.Current.Trace.Write("from Database.."); 



 



<%@ Page Language="c#" Trace="true" %> 



<%@ import Namespace="System" %> 



<%@ import Namespace="System.Data" %> 



<%@ import Namespace="System.Data.SqlClient" %> 



<%@ import Namespace="System.Configuration" %> 



<%@ import Namespace="System.Web" %> 



<%@ import Namespace="System.Collections" %> 



<%@ import Namespace="System.IO" %> 



<script runat="server">
   1:  
   2: void Page_Load(Object sender, EventArgs e) 
   3: { 
   4: DataSet dsUsers; 
   5: try 
   6: { 
   7: if(Cache["Users"]==null) 
   8: { 
   9: SqlConnection cn; 
  10: dsUsers = new DataSet("new"); 
  11: cn = new SqlConnection(ConfigurationSettings.AppSettings.Get("conn")); 
  12: SqlDataAdapter daUsers; 
  13: daUsers = new SqlDataAdapter("Select * from tblUsers",cn); 
  14: cn.Open(); 
  15: daUsers.Fill(dsUsers,"tblUsers"); 
  16: //Update the cache object 
  17: Cache.Insert("Users",dsUsers, new System.Web.Caching.CacheDependency( 
  18: Server.MapPath("Master.xml")), DateTime.Now.AddSeconds(45),TimeSpan.Zero); 
  19: HttpContext.Current.Trace.Write(DateTime.Now.AddSeconds(45).ToString() + " 
  20: is expiry time.."); 
  21: cn.Close(); 
  22: cn.Dispose(); 
  23: HttpContext.Current.Trace.Write("from Database.."); 
  24: lblChange.Text ="From the database...."; 
  25: } 
  26: else 
  27: { 
  28: HttpContext.Current.Trace.Write("From cache.."); 
  29: lblChange.Text ="From the cache...."; 
  30: dsUsers= (DataSet) Cache["Users"]; 
  31: } 
  32: dlUsers.DataSource =dsUsers; 
  33: dlUsers.DataMember = dsUsers.Tables[0].TableName ; 
  34: //lblChange.Text += Server.MapPath("Master.xml"); 
  35: this.DataBind(); 
  36: } 
  37: catch(Exception ex) 
  38: { 
  39: lblChange.Text = ex.Message; 
  40: } 
  41: } 
</script>



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 



<html> 



<head> 



<title>Cache Dependency Tester</title> 



<meta content="Microsoft Visual Studio 7.0" name="GENERATOR" /> 



<meta content="C#" name="CODE_LANGUAGE" /> 



<meta content="JavaScript" name="vs_defaultClientScript" /> 



<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema" /> 



</head> 



<body ms_positioning="GridLayout"> 



<form id="Form1" method="post" runat="server"> 



<asp:DataList id="dlUsers" style="Z-INDEX: 101; LEFT: 44px; POSITION: absolute; TOP: 104px" runat="server" Height="148px" Width="343px" BorderWidth="1px" GridLines="Horizontal" CellPadding="4" BackColor="White" ForeColor="Black" BorderStyle="None" BorderColor="#CCCCCC"> 



<SelectedItemStyle font-bold="True" forecolor="White" backcolor="#CC3333"></SelectedItemStyle> 



<FooterStyle forecolor="Black" backcolor="#CCCC99"></FooterStyle> 



<HeaderStyle font-bold="True" forecolor="White" backcolor="#333333"></HeaderStyle> 



<ItemTemplate> 



<table> 



<tr> 



<td> 



<%
   1: #DataBinder.Eval(Container.DataItem,"UserId")
%></td>



<td> 



<%
   1: #DataBinder.Eval(Container.DataItem,"FirstName")
%></td>



<td> 



<%
   1: #DataBinder.Eval(Container.DataItem,"LastName")
%></td>



</tr> 



</table> 



</ItemTemplate> 



</asp:DataList> 



<asp:Label id="lblChange" style="Z-INDEX: 102; LEFT: 46px; POSITION: absolute; TOP: 63px" runat="server" Height="28px" Width="295px"></asp:Label> 



<asp:Button id="btnMaster" style="Z-INDEX: 103; LEFT: 50px; POSITION: absolute; TOP: 293px" onclick="btnMaster_Click" runat="server" Text="Refresh Master"></asp:Button> 



</form> 



</body> 



</html> 





We created the page that initiates and uses the Cache. For testing purpose we need another page that will overwrite this "Master.xml" on click of a button for which the code snippet is as follows. This ideally should be our master maintenance page that adds/updates Master records in database and overwrites the XML. But to make it easy I have just written an overwriting sample.





<%@ Page Language="C#" Trace="true"%> 



<%@ import Namespace="System" %> 



<%@ import Namespace="System.Data" %> 



<%@ import Namespace="System.Data.SqlClient" %> 



<script runat="server">
   1:  
   2: void btnMaster_Click(Object sender, EventArgs e) 
   3: { 
   4: //Call save function 
   5: this.Save(); 
   6: } 
   7: void Save() 
   8: { 
   9: try 
  10: { 
  11: SqlConnection cn; 
  12: DataSet dsUsers = new DataSet("Users"); 
  13: //I have used this to get the Connectionstring from the 
  14: //Configuration file. 
  15: cn = new SqlConnection(ConfigurationSettings.AppSettings.Get("conn")); 
  16: SqlDataAdapter daQualification; 
  17: SqlDataAdapter daLocations; 
  18: daQualification = new SqlDataAdapter("Select * from tblqualifications",cn); 
  19: daLocations = new SqlDataAdapter("Select * from tblLocations",cn); 
  20: cn.Open(); 
  21: daQualification.Fill(dsUsers,"tblqualifications"); 
  22: daLocations.Fill(dsUsers,"tblLocations"); 
  23: HttpContext.Current.Trace.Write("Masters data up.."); 
  24: //Overwrite the XML file. Also please read MSDN on the overloaded parameters for WriteXml 
  25: dsUsers.WriteXml(HttpContext.Current.Server.MapPath 
  26: "Master.xml"),XmlWriteMode.WriteSchema); 
  27: cn.Close(); 
  28: cn.Dispose(); 
  29:  
  30: Technorati Tags: Asp.net,Caching,C#
  31: } 
  32: catch(Exception ex) 
  33: { 
  34: throw new Exception(ex.Message); 
  35: } 
  36: } 
</script>



<html> 



<head> 



</head> 



<body> 



<form runat="server" ID="Form1"> 



<span> 



<table> 



<tbody> 



<tr> 



<td> 



<label id="lblRefresh" runat="server"> 



Rewrite the XML File by clicking the buttonbelow.</label> 



</td> 



</tr> 



<tr align="middle"> 



<td> 



<asp:Button id="btnMaster" onclick="btnMaster_Click" runat="server" 



Text="Write XML"></asp:Button> 



</td> 



</tr> 



</tbody> 



</table> 



</span> 



</form> 



</body> 



</html> 




Now once you have created the above pages i.e. one that implements caching and other that overwrites the dependency file, create two instance of browser and open the cache implementation page and note for trace, label text; open the other instance of browser with the page which overwrites the XML. Note the former, the first time it fetches data from the database and the subsequent request will be from cache till your expiration time of 45 seconds is reached or anyone overwrites or changes the "Master.xml" file. Also give a look on Timespan parameter since you have a concept of Sliding expiration that can also be implemented. Keep refreshing the first page and you will see that trace indicates the cached page retrieval. Click the overwrite XML button on the latter page that would overwrite the XML and again refresh the former page to note that the data is retrieved from database. Though in this example I have not shown any direct relation between the cached data and the dependency file (like get values from dependency file and merge with cached object etc) in terms of integrated usage, this could very easily be designed and implemented. Dependency caching is a powerful technique that .NET supports and should be utilized wherever applicable.

Block or Disable Cut, Copy and Paste operation in ASP.Net

 
Block or Disable Cut, Copy and Paste operation in ASP.Net TextBox Using jQuery

It is required to block the cut, copy and paste operations on some of the textbox in an ASP.Net. For example, it will be better if we do not allow users to copy paste the data entered in Email and Confirm Email field in order to make the user to type themselves.

The below jQuery code will help us to do the same using preventDefault() method.

<script src="_scripts/jquery-1.4.1.min.js" type="text/javascript"></script>   
    <script type="text/javascript">
        $(function() {
        $("#<% =txtEmail.ClientID %>,#<% =txtConfirmEmail.ClientID%>").bind("cut copy paste", function(event) {
                event.preventDefault();
            });
        });
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>   
        <b>Email </b><asp:TextBox ID="txtEmail" runat="server"></asp:TextBox><br />
        <b>Confirm Email </b><asp:TextBox ID="txtConfirmEmail" runat="server"></asp:TextBox>

 

Block Right Click in asp.net  

If you want to block right click copy code in master page.

<SCRIPT language=JavaScript>
<!--  -->
    var message = "function disabled";
    function rtclickcheck(keyp){ if (navigator.appName == "Netscape" && keyp.which == 3){     alert(message); return false; }
    if (navigator.appVersion.indexOf("MSIE") != -1 && event.button == 2) {     alert(message);     return false; } }
    document.onmousedown = rtclickcheck;
</SCRIPT>

Thursday, February 24, 2011

Filtering or Searching in Listbox Item Using JavaScript

Normally you have a requirement that user want to search or filtering record in a list box according to what he write in textbox.So in my pervious posted Search ListBox items using JavaScript.I explained how to search in listbox but there is one restriction when user want to search, it will select only one record and user can not see the other records related to searching criteria.So in this post I explain how to implement this thing if you have that kind or requirement.

First you write JavaScript code on html page.

 
<script type="text/javascript" language="javascript">
var ddlText, ddlValue, ddl, lblMesg;
function CacheItems() {

ddlText = new Array();
ddlValue = new Array();
ddl = document.getElementById("<%=ListBox1.ClientID %>");
lblMesg = document.getElementById("<%=lblMessage.ClientID%>");
for (var i = 0; i < ddl.options.length; i++) {
ddlText[ddlText.length] = ddl.options[i].text;
ddlValue[ddlValue.length] = ddl.options[i].value;
}
}
window.onload = CacheItems;

function FilterItems(value) {
ddl.options.length = 0;

for (var i = 0; i < ddlText.length; i++) {

if (ddlText[i].toLowerCase().indexOf(value) != -1) {

AddItem(ddlText[i], ddlValue[i]);

}

}

lblMesg.innerHTML = ddl.options.length + " items found.";

if (ddl.options.length == 0) {

AddItem("No items found.", "");

}

}



function AddItem(text, value) {

var opt = document.createElement("option");

opt.text = text;

opt.value = value;

ddl.options.add(opt);

}
</script>



 



The above three JavaScript methods take care of the Filtering and Searching process. The significance of the these methods is described below


1. CacheItems


This method is called on the window onload event. The job of this method is to populate text and value arrays that will be used to cache the List box items.


2. FilterItems


This method is called when keyup event fires in the Search TextBox. This method searches for the string segment and filters the Listbox items.


3. AddItem


This method as the name suggests adds a new item to the Listbox


<body> 

<form id="form1" runat="server">

<asp:TextBox ID="TextBox1" runat="server" onkeyup="FilterItems(this.value)"><br />

<asp:ListBox ID="ListBox1" runat="server" Height="150px" Width="250px">

<asp:ListItem>Vincent</asp:ListItem>

<asp:ListItem>Jennifer</asp:ListItem>

<asp:ListItem>Shynne</asp:ListItem>

<asp:ListItem>Christian</asp:ListItem>

<asp:ListItem>Helen</asp:ListItem>

<asp:ListItem>Vladi</asp:ListItem>

<asp:ListItem>Bee</asp:ListItem>

<asp:ListItem>Jerome</asp:ListItem>

<asp:ListItem>Vinz</asp:ListItem>

<asp:ListItem>Churchill</asp:ListItem>

<asp:ListItem>Rod</asp:ListItem>

<asp:ListItem>Mark</asp:ListItem>

</asp:ListBox>
<asp:Label ID="lblMessage" runat="server" Text=""></asp:Label>
</form>

</body>

</html>


The JavaScript function basically searches the ListBox items and find the items based from the value of the TextBox that was entered. If a keyword exist from the list then it will 
automatically select the ListItems in the ListBox, but if the keyword does not exist then it will clear the ListBox selection.While the label will display the status message to the user

Friday, February 4, 2011

Avoid Multiple Form Submits

 
Multiple form submits is a serious issue in web applications because it’ll result in unexpected behavior like multiple entries in database .I have spent some time for the same in Google and I got some solutions for that.
If you are submitting the page only once then you can use,
<form onsubmit="return Submit();">
And the method is like,
 

<script type="text/javascript">
var flag = false;
function Submit() {
if (flag) {
return false;
}
else {
flag = true;
return true;
}
}
</script>
 



For a single button you can use,

 
btnSubmit.Attributes["onclick"] = "this.disabled=true;" + GetPostBackEventReference(btnSubmit);




 


For pages with update panels multiple submit is a serious issue as page is posting asynchronously or partially.In that scenario you can use Sys.WebForms.PageRequestManager for fixing the issue,

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<script type="text/javascript">
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(BeginRequest);
function BeginRequest(sender, e) {
e.get_postBackElement().disabled = true;
}
</script>

Tuesday, February 1, 2011

Auto-Refreshing ASP.NET Web Pages

 

Today I am writing about how you can auto-refresh the page without user click .If you want to refresh the page at specific time of interval like after each 10 seconds you can used any of the following methods.

HTML header refresh tag

 

    The most common and best known way to tag of the following format is placed in the HTML section of the page:

    <meta http-equiv="refresh" content=" 5; url=http://dotnetfarrukhabbas.blogspot.com/">

    • where '5' refers to the number of seconds that will elapse before the page is refreshed;

    • 'url' is the new url redirect to. It can be excluded which means the current page will be reloaded.

      This construct is useful if you have one or two pages which have to auto-refresh, and works for any HTML content type forms.

      You can used this meta tag in master page as well as any specific page.

       

      Using JavaScript

      You can also used the JavaScript for auto refreshing the page instead of meta tag.

      <script language="javascript" type="text/javascript"> 

      setTimeout("StratRefresh()", 30000);
      function StratRefresh() {
      window.location.reload();
      }
      </script>



       


      Refresh Page from Server Side


      ASP.NET provides the AppendHeader method to the Response object. Typically the page refresh can be set as follows in an ASP.NET webform (in C#):

      protected void Page_Load(object sender, EventArgs e)
      {
      if (!Page.IsPostBack)
      {
      //page will be refereshed at a interval of 10 sec
      Response.AddHeader("Refresh", "10");
      }
      }



      This construct is useful as it can be placed in a base webform OnLoad() or Page_Load() response method. All derived webforms will then have the same page refresh setting when they are loaded.


      Note 


      when the page gets refresh then it will not persist the view-state of the page.

      Custom Paging And Sorting Using Oracle Stored Procedure.



      Here I will explain how to create Oracle stored procedure for custom paging,sorting and base on culture .Normally you should know how many record found in table base on where clause as well as required dynamic sorting and paging.All these things possible using dynamic creation of oracle stored procedure see this give below example.

      
      

      CREATE OR REPLACE PROCEDURE GET_COUNTRY
      (
      //-------- Table Paramerters--------------------------------
      V_COUNTRY_NO IN TRN_ORG_SYS.COUNTRY.COUNTRY_NO%TYPE DEFAULT NULL
      ,V_COUNTRY_NAME_AR IN TRN_ORG_SYS.COUNTRY.COUNTRY_NAME_AR%TYPE DEFAULT NULL
      ,V_COUNTRY_NAME_EN IN TRN_ORG_SYS.COUNTRY.COUNTRY_NAME_EN%TYPE DEFAULT NULL
      ,V_CREATED_BY IN TRN_ORG_SYS.COUNTRY.CREATED_BY%TYPE DEFAULT NULL
      ,V_CREATED_ON IN TRN_ORG_SYS.COUNTRY.CREATED_ON%TYPE DEFAULT NULL
      ,V_MODIFIED_BY IN TRN_ORG_SYS.COUNTRY.MODIFIED_BY%TYPE DEFAULT NULL
      ,V_MODIFIED_ON IN TRN_ORG_SYS.COUNTRY.MODIFIED_ON%TYPE DEFAULT NULL
      ,V_ISDELETED IN TRN_ORG_SYS.COUNTRY.ISDELETED%TYPE DEFAULT NULL
      
      //-------- Parameters of Paging Sorting and culture------------
      ,P_CULTURE IN VARCHAR2 DEFAULT NULL
      ,P_SORT_ORDER IN VARCHAR2 DEFAULT NULL
      ,P_SORT_FIELD IN VARCHAR2 DEFAULT NULL
      ,P_PAGE_NO_NEEDED IN NUMBER DEFAULT NULL
      ,P_NUM_PER_PAGE IN NUMBER DEFAULT NULL
      ,P_OUT_TOTAL_RECORDS OUT NUMBER
      ,ITEMS_CURSOR OUT TRN_ORG_PROC.REF_CURSOR.T_CURSOR
      )
      IS
      --Local variables >>>>>>>
      SQL_SELECT CLOB;
      SQL_SELONE VARCHAR2(4000);
      SQL_SELTWO VARCHAR2(4000);
      SQL_COUNTONE VARCHAR2(50) := 'SELECT COUNT(*) FROM ( ';
      SQL_COUNTTWO VARCHAR2(50) := ') ';
      SQL_ORDER_BY VARCHAR2(100);
      FROM_ROWNUM NUMBER;
      TO_ROWNUM NUMBER;
      V_NUM_PER_PAGE NUMBER := P_NUM_PER_PAGE;
      V_PAGE_NO_NEEDED NUMBER := P_PAGE_NO_NEEDED;
      V_SORT_FIELD VARCHAR2(30);
      V_SORT_ORDER VARCHAR2(30);
      NEWLINE VARCHAR2(10) := CHR(13) || CHR(10);
      
      
      
      --Local variables <<<<<<<
      BEGIN
      IF (V_NUM_PER_PAGE IS NULL OR V_NUM_PER_PAGE <= 0) THEN
      V_NUM_PER_PAGE := 25;
      END IF;
      IF (V_PAGE_NO_NEEDED IS NULL OR V_PAGE_NO_NEEDED <= 0) THEN
      V_PAGE_NO_NEEDED := 1;
      END IF;
      IF (P_SORT_FIELD IS NULL) THEN
      V_SORT_FIELD := ' COUNTRY_NO';
      ELSE
      V_SORT_FIELD := P_SORT_FIELD;
      END IF;
      IF (P_SORT_ORDER IS NULL) THEN
      V_SORT_ORDER := 'ASC';
      ELSE
      V_SORT_ORDER := P_SORT_ORDER;
      END IF;
      --
      FROM_ROWNUM := ((V_PAGE_NO_NEEDED - 1) * V_NUM_PER_PAGE) + 1;
      TO_ROWNUM := FROM_ROWNUM -1 + V_NUM_PER_PAGE;
      SQL_SELONE := SQL_SELONE || 'SELECT ' || NEWLINE;
      SQL_SELONE := SQL_SELONE || ' b.* ' || NEWLINE;
      SQL_SELONE := SQL_SELONE || ' FROM ( ' || NEWLINE;
      SQL_SELONE := SQL_SELONE || ' SELECT ' || NEWLINE;
      SQL_SELONE := SQL_SELONE || ' a.*, ' || NEWLINE;
      SQL_SELONE := SQL_SELONE || ' ROWNUM rnum ' || NEWLINE;
      SQL_SELONE := SQL_SELONE || ' FROM ( ' || NEWLINE;
      --
      SQL_SELECT := SQL_SELECT || 'SELECT TRN_ORG_SYS.COUNTRY.COUNTRY_NO, 
      DECODE('''|| P_CULTURE ||''''||',
      ''en-US'',TRN_ORG_SYS.COUNTRY.COUNTRY_NAME_EN ,
      ''ar-KW'',TRN_ORG_SYS.COUNTRY.COUNTRY_NAME_AR,
      TRN_ORG_SYS.COUNTRY.COUNTRY_NAME_EN) COUNTRY_NAME,
      TRN_ORG_SYS.COUNTRY.COUNTRY_NAME_AR, 
      TRN_ORG_SYS.COUNTRY.COUNTRY_NAME_EN, 
      TRN_ORG_SYS.COUNTRY.CREATED_BY, 
      TRN_ORG_SYS.COUNTRY.CREATED_ON, 
      TRN_ORG_SYS.COUNTRY.MODIFIED_BY, 
      TRN_ORG_SYS.COUNTRY.MODIFIED_ON, 
      TRN_ORG_SYS.COUNTRY.ISDELETED 
      FROM TRN_ORG_SYS.COUNTRY' || NEWLINE;
      --Construction of Where clause Starts here
      SQL_SELECT := SQL_SELECT || ' WHERE 1 = 1 ' || NEWLINE;
      
      IF(V_COUNTRY_NO IS NOT NULL AND V_COUNTRY_NO > 0 ) THEN
      SQL_SELECT := SQL_SELECT || ' AND COUNTRY.COUNTRY_NO = ' || V_COUNTRY_NO || '' || NEWLINE;
      END IF; 
      IF(V_COUNTRY_NAME_AR IS NOT NULL) THEN
      SQL_SELECT := SQL_SELECT || ' AND COUNTRY.COUNTRY_NAME_AR Like ''%' || V_COUNTRY_NAME_AR || '%''' || NEWLINE;
      END IF; 
      IF(V_COUNTRY_NAME_EN IS NOT NULL) THEN
      SQL_SELECT := SQL_SELECT || ' AND COUNTRY.COUNTRY_NAME_EN Like ''%' || V_COUNTRY_NAME_EN || '%''' || NEWLINE;
      END IF; 
      IF(V_CREATED_BY IS NOT NULL) THEN
      SQL_SELECT := SQL_SELECT || ' AND COUNTRY.CREATED_BY Like ''%' || V_CREATED_BY || '%''' || NEWLINE;
      END IF; 
      IF(V_CREATED_ON IS NOT NULL) THEN
      SQL_SELECT := SQL_SELECT || ' AND COUNTRY.CREATED_ON = ''' || V_CREATED_ON || '''' || NEWLINE;
      END IF; 
      IF(V_MODIFIED_BY IS NOT NULL) THEN
      SQL_SELECT := SQL_SELECT || ' AND COUNTRY.MODIFIED_BY Like ''%' || V_MODIFIED_BY || '%''' || NEWLINE;
      END IF; 
      IF(V_MODIFIED_ON IS NOT NULL) THEN
      SQL_SELECT := SQL_SELECT || ' AND COUNTRY.MODIFIED_ON = ''' || V_MODIFIED_ON || '''' || NEWLINE;
      END IF; 
      IF(V_ISDELETED IS NOT NULL AND V_ISDELETED > 0 ) THEN
      SQL_SELECT := SQL_SELECT || ' AND COUNTRY.ISDELETED = ' || V_ISDELETED || '' || NEWLINE;
      END IF; 
      --Construction of Where clause Ends here
      
      SQL_ORDER_BY := SQL_ORDER_BY || ' ORDER BY lower(' || V_SORT_FIELD || ') ' || V_SORT_ORDER || NEWLINE;
      --
      SQL_SELTWO := SQL_SELTWO || ' ) a ' || NEWLINE;
      SQL_SELTWO := SQL_SELTWO || ' WHERE ' || NEWLINE;
      SQL_SELTWO := SQL_SELTWO || ' ROWNUM <= :2) b ' || NEWLINE; -- TO_ROWNUM
      SQL_SELTWO := SQL_SELTWO || ' WHERE ' || NEWLINE;
      SQL_SELTWO := SQL_SELTWO || ' rnum >= :3 ' || NEWLINE; -- FROM_ROWNUM
      --
      EXECUTE IMMEDIATE SQL_COUNTONE || TO_CHAR(SQL_SELECT) || SQL_COUNTTWO INTO P_OUT_TOTAL_RECORDS;
      --
      OPEN ITEMS_CURSOR FOR SQL_SELONE || TO_CHAR(SQL_SELECT) || SQL_ORDER_BY || SQL_SELTWO USING TO_ROWNUM, FROM_ROWNUM;
      
      EXCEPTION
      WHEN NO_DATA_FOUND THEN
      NULL;
      WHEN OTHERS THEN
      -- Consider logging the error and then re-raise
      RAISE;
      END GET_COUNTRY;
      


      Base on above example you can easily create oracle stored procedure for custom paging, sorting,total record found and base on culture.

      call server side method from client side using script manager

       

       

       

      Hello friends.

      I am going to share with you a concept to call server side method from client side using script manager.

      Step 1 : Put ScriptManager on .ASPX page.

      Step 2 : Set EnablePageMethods="True" in ScriptManager.

      Step 3 : Create one static method in server side that return some value.

      Step 4 : Set WebMethod attribute to above the method.

      Step 5 : Create one javascript  function and call server side method using PageMethods object and set callback method as argument.

      Step 6 : Create callback method where you will be able to retrieve return parameter from server side method.

      See following example code

      ScriptManager on the page.

      <asp:ScriptManager ID="ScriptManager1"  EnablePageMethods="true" runat="server">
      </asp:ScriptManager>



      My server side static method

      [System.Web.Services.WebMethod]
      public static int Sum(int value1, int value2)
      {
      return value1 + value2;
      }



      My javascript function to call server side method and retrieve result from server side

      <script language="javascript" type="text/javascript">
      pageMethodConcept={
      callServerSideMethod:function(){
      PageMethods.Sum(3,4,pageMethodConcept.callback);

      // I am passing 3 and 4 to get sum and set callback method
      },
      callback:function(result){
      alert(result);
      }
      }
      window.onload=pageMethodConcept.callServerSideMethod;
      </script>

      PDF Arabic watermark using MVC and iTextSharp

      PDF full page Arabic watermark using MVC and iTextSharp Download :  Source Code Most of the time we have requirement to  gen...