Wednesday, September 11, 2013

ASP.Net Tutorial Series III


Different page navigation techniques in asp.net
What are the different page navigation techniques in asp.net?

OR
How do you move from one webform to another webform in asp.net?

OR
How do you link pages in an application?  
This is a very common interview question in asp.net. There are several techniques to navigate between webforms in asp.net as listed below.
1. Hyperlink control - Is used to navigate to another page. The page you want to navigate to is specified by the NavigateURL property. Using hyperlink, you can navigate to another page with in the same application or to an external web site. The hyperlink control is rendered as an HTML anchor tag. We have discussed in detail about the HyperLink control in Part 13 of ASP.NET video series.
2. Response.Redirect 
3. Server.Transfer 
4. Server.Execute
5. Cross-Page postback
6. Window.Open 
We will discuss about the rest of the page navigation techniques in the subsequent videos.
The following are the different page navigation techniques in asp.net
1. Hyperlink control -
2. Response.Redirect
3. Server.Transfer
4. Server.Execute
5. Cross-Page postback
6. Window.Open 
In this video, We will discuss about Response.Redirect. Response.Redirect is similar to clicking on a hyperlink. The Hyperlink control does not expose any server side events. So when the user clicks on a hyperlink, there is no server side event to intercept the click.
So, if you want to intercept a click event in code, use the Button, LinkButton or the ImageButton server control. In the button click event, call Response.Redirect() method. When the user clicks the button, the web server receives, a request for redirection. The server then sends a response header to the client. The client then automatically issues a new GET request to the web server. The web server will then serve the new page. So, in short, Response.Redirect causes 2 request/response cycles.
Also, note that when Response.Redirect is used the URL in the address bar changes and the browser history is maintained.
Response.Redirect() can be used to navigate pages/websites on the same web server or on a different web server.


Server.Transfer in asp.net
The following are the different page navigation techniques in asp.net
1. Hyperlink control -
2. Response.Redirect -
3. Server.Transfer
4. Server.Execute
5. Cross-Page postback
6. Window.Open
In this video, We will discuss about 
1. Server.Transfer
2. Difference between Server.Transfer and Response.Redirect
Create an asp.net web application and add 2 webforms. Copy and paste the following HTML on WebForm1.aspx
<div style="font-family: Arial">
    <table>
        <tr>
            <td colspan="2">
                <h1>
                    This is WebForm1</h1>
            </td>
        </tr>
        <tr>
            <td>
                <b>Name</b>
            </td>
            <td>
                :<asp:TextBox ID="txtName" runat="server">
                </asp:TextBox>
            </td>
        </tr>
        <tr>
            <td>
                <b>Email</b>
            </td>
            <td>
                :<asp:TextBox ID="txtEmail" runat="server">
                </asp:TextBox>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Button ID="btnTransfer" runat="server"
                    Text="Transfer to WebForm2" Width="250px"
                    OnClick="btnTransfer_Click"/>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Button ID="btnTransferToExternalWebsite"
                runat="server" Width="250px"
                OnClick="btnTransferToExternalWebsite_Click"
                Text="Transfer to External WebSite"/>
            </td>
        </tr>
    </table>
</div>
Code-Behind code for WebForm1.aspx.cs
protected void btnTransfer_Click(object sender, EventArgs e)
{
   
//Send the user to webform2 using Server.Transfer
    //Set the boolean parameter preserveForm=true
    //This ensures that the posted form values can be retrieved
    //Since the default value for this parameter is true, the 
    //form values are preserved, even if this parameter is not used.
    Server.Transfer(
"~/WebForm2.aspx", true);
}
protected void btnTransferToExternalWebsite_Click(object sender, EventArgs e)
{
   
//Transfer to websites/pages on a different web server causes
    //runtime error
    Server.Transfer(
"http://pragimtech.com/home.aspx");
}

WebForm2.aspx code:
<div>
    <table>
        <tr>
            <td>
                <b>Name</b>
            </td>
            <td>
                :<asp:Label ID="lblName" runat="server">
                </asp:Label>
            </td>
        </tr>
        <tr>
            <td>
                <b>Email</b>
            </td>
            <td>
                :<asp:Label ID="lblEmail" runat="server">
                </asp:Label>
            </td>
        </tr>
    </table>
</div>

WebForm2.aspx.cs code
protected void Page_Load(object sender, EventArgs e)
{
   
//Get the form values from the previous page
    System.Collections.Specialized.NameValueCollection nameValueCollection =
        Request.Form;

    lblName.Text = nameValueCollection[
"txtName"];
    lblEmail.Text = nameValueCollection[
"txtEmail"];

   
//Page previousPage = this.Page.PreviousPage;
    //if (previousPage != null)
    //{
    //    TextBox previousPageNameTextBox = (TextBox)previousPage.FindControl("txtName");
    //    lblName.Text = previousPageNameTextBox.Text;

    //    TextBox previousPageEmailTextBox = (TextBox)previousPage.FindControl("txtEmail");

    //    lblEmail.Text = previousPageEmailTextBox.Text;
    //}
}

The following are the differences between Server.Transfer and Response.Redirect
1. Just like hyperlink and Response.Redirect, Server.Transfer is used to navigate to other pages/sites running on the same web server.
2. Server.Transfer cannot be used to navigate to sites/pages on a different web server.
3. Server.Transfer does not change the URL in the address bar
4. Server.Transfer is faster than Response.Redirect as the redirection happens on the server in one Request/Response cycle. Response.Redirect() involves 2 Request/Response cycles.
5. With Server.Transfer the Form Variables from the original request are preserved.

Server.execute in asp.net 

The following are the different page navigation techniques in asp.net
1. Hyperlink control - Discussed in
Part 13 and Part 51 of the ASP.NET video series
2. Response.Redirect - Discussed in
Part 52
3. Server.Transfer - Discussed in
Part 53
4. Server.Execute
5. Cross-Page postback
6. Window.Open 
In this video we will discuss about
1. Server.Execute method
2. Difference between Server.Transfer and Server.Execute

Server.Transfer and Server.Execute are similar in many ways.
1. The URL in the browser remains the first page URL.
2. Server.Transfer and Server.Execute can only be used to navigate to sites/pages on the same web server. Trying to navigate to sites/pages on a different web server, causes runtime exception.
3. Server.Transfer and Server.Execute preserves the Form Variables from the original request.

The major difference between Server.Transfer and Server.Execute is that, Server.Transfer terminates the execution of the current page and starts the execution of the new page, where as Server.Execute process the second Web form without leaving the first Web form. After completing the execution of the first webform, the control returns to the second webform.

WebForm1.aspx code:
<div style="font-family: Arial">
    <table>
        <tr>
            <td colspan="2">
                <h1>
                    This is WebForm1</h1>
            </td>
        </tr>
        <tr>
            <td>
                <b>Name</b>
            </td>
            <td>
                :<asp:TextBox ID="txtName" runat="server">
                </asp:TextBox>
            </td>
        </tr>
        <tr>
            <td>
                <b>Email</b>
            </td>
            <td>
                :<asp:TextBox ID="txtEmail" runat="server">
                </asp:TextBox>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Button ID="btnExecute" runat="server"
                Text="Server.Execute - WebForm2"
                Width="250px" onclick="btnExecute_Click"/>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Button ID="btnExecuteToExternalWebsite"
                runat="server" Width="250px"
                Text="Server.Execute - External WebSite"
                onclick="btnExecuteToExternalWebsite_Click" />
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Label ID="lblStatus" ForeColor="Green"
                Font-Bold="true" runat="server"></asp:Label>
            </td>
        </tr>
    </table>
</div>

WebForm1.aspx.cs code:
protected void btnExecute_Click(object sender, EventArgs e)
{
    Server.Execute(
"~/WebForm2.aspx", true);
    lblStatus.Text =
"The call returned after processing the second webform";
}
protected void btnExecuteToExternalWebsite_Click(object sender, EventArgs e)
{
    Server.Execute(
"http://pragimtech.com/home.aspx");
}

WebForm2.aspx code:
<div style="font-family: Arial">
    <table>
        <tr>
            <td colspan="2">
                <h1>This is WebForm2</h1>
            </td>
        </tr>
        <tr>
            <td>
                <b>Name</b>
            </td>
            <td>
                :<asp:Label ID="lblName" runat="server">
                </asp:Label>
            </td>
        </tr>
        <tr>
            <td>
                <b>Email</b>
            </td>
            <td>
                :<asp:Label ID="lblEmail" runat="server">
                </asp:Label>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Button ID="btnPostBack" runat="server"
                Text="Simply Post Back" />
            </td>
        </tr>
    </table>
</div>

WebForm2.aspx.cs code:
protected void Page_Load(object sender, EventArgs e)
{
    System.Collections.Specialized.NameValueCollection previousFormcollection = Request.Form;
    lblName.Text = previousFormcollection[
"txtName"];
    lblEmail.Text = previousFormcollection[
"txtEmail"];

    //Page previousPage = Page.PreviousPage;
    //if (previousPage != null)
    //{
    //    lblName.Text = ((TextBox)previousPage.FindControl("txtName")).Text;
    //    lblEmail.Text = ((TextBox)previousPage.FindControl("txtEmail")).Text;
    //}
}


Cross page posting in asp.net

The following are the different page navigation techniques in asp.net
1. Hyperlink control -
2. Response.Redirect -
3. Server.Transfer -
4. Server.Execute -
5. Cross-Page postback
6. Window.Open 
In this video we will discuss about Cross page posting. Cross page posting allows to post one page to another page. By default, when you click a button, the webform posts to itself. If you want to post to another webform on a button click, set the PostBackUrl of the button, to the page that you want to post to.
WebForm1.aspx code: Notice that, the PostBackUrl property of the button with ID=btnCrossPagePostback is set to WebForm2.aspx. When this button is clicked WebForm1.aspx gets posted to WebForm2.aspx.
<div style="font-family: Arial">
    <table>
        <tr>
            <td colspan="2">
                <h1>
                    This is WebForm1</h1>
            </td>
        </tr>
        <tr>
            <td>
                <b>Name</b>
            </td>
            <td>
                :<asp:TextBox ID="txtName" runat="server">
                </asp:TextBox>
            </td>
        </tr>
        <tr>
            <td>
                <b>Email</b>
            </td>
            <td>
                :<asp:TextBox ID="txtEmail" runat="server">
                </asp:TextBox>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Button ID="btnCrossPagePostback" runat="server"
                Text="Cross Page Postback - WebForm2"
                Width="250px" PostBackUrl="~/WebForm2.aspx"/>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Button ID="Button1" runat="server" onclick="Button1_Click"
                    Text="Server.Transfer - WebForm2" Width="250px" />
            </td>
        </tr>
        </table>
</div>

WebForm1.aspx.cs code:
protected void Button1_Click(object sender, EventArgs e)
{
    Server.Transfer(
"~/WebForm2.aspx");
}

WebForm2.aspx code:
<div style="font-family: Arial">
    <table>
        <tr>
            <td colspan="2">
                <h1>This is WebForm2</h1>
            </td>
        </tr>
        <tr>
            <td>
                <b>Name</b>
            </td>
            <td>
                :<asp:Label ID="lblName" runat="server">
                </asp:Label>
            </td>
        </tr>
        <tr>
            <td>
                <b>Email</b>
            </td>
            <td>
                :<asp:Label ID="lblEmail" runat="server">
                </asp:Label>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Label ID="lblStatus" runat="server"
                ForeColor="Red" Font-Bold="true"></asp:Label>
            </td>
        </tr>
        </table>
</div>

WebForm2.aspx.cs code: Page.IsCrossPagePostBack Property is used to indicate whether the page is involved in a cross-page postback.
protected void Page_Load(object sender, EventArgs e)
{
    Page previousPage = Page.PreviousPage;
   
if (previousPage != null && previousPage.IsCrossPagePostBack)
    {
        lblName.Text = ((TextBox)previousPage.FindControl(
"txtName")).Text;
        lblEmail.Text = ((TextBox)previousPage.FindControl(
"txtEmail")).Text;
    }
   
else
    {
        lblStatus.Text =
"Landed on this page using a technique other than cross page post back";
    }
}

The problem with FindControl() method is that, if you mis-spell the ControlID, we could get a
runtime NullRefernceException. In the next video we will discuss about obtaining a strongly typed reference to the previous page, which can avoid NullRefernceExceptions.

Cross page postback strongly typed reference
The following are the different page navigation techniques in asp.net
1. Hyperlink control -
2. Response.Redirect –

3. Server.Transfer -
4. Server.Execute -
5. Cross-Page postback
6. Window.Open 

In the previous session, we used FindControl() method to get a reference to the TextBox on the previous page. The problem with FindControl() method is that, if we mis-spell the ID of the control, we don't get any compile time errors, but may cause runtime nullreference exceptions.

In this session, we will discuss about, obtaining a strongly types reference to the previous page. There are 2 ways to obtain a strongly typed reference. We will explore both of these options in this part of the video. We will be using the same example used in Part 55.

The first step in obtaining a strongly typed reference, is to create public properties. We want to convert the values of TextBox controls(txtName and txtEmail) into properties(Name and Email) respectively. The Name and Email properties are created as Read-Only properties, as we just need to read the values on the destination page.
//Name - read only property
public string Name
{
   
get
    {
       
return txtName.Text;
    }
}
//Email - read only property
public string Email
{
   
get
    {
       
return txtEmail.Text;
    }
}

The next step is to obtain a strongly typed reference to the previous page and access the public propertie as shown below. This code must be in the Page_Load event on WebForm2.aspx.cs. If Name or Email properties are mis-spelled, we get an immediate compile time error. Hence, strongly typed references can eliminate runtime nullreference exceptions.
protected void Page_Load(object sender, EventArgs e)
{
   
//Type cast PreviousPage to WebForm1
   
WebForm1 previousPage = (WebForm1)Page.PreviousPage;
    if (previousPage !=
null && previousPage.IsCrossPagePostBack)
    {
       
//Access the Name and Email public properties
        lblName.Text = previousPage.Name;
        lblEmail.Text = previousPage.Email;
    }
   
else
    {
        lblStatus.Text =
"You landed on this page using a technique other than cross page post back";
    }
}

PreviousPageType directive can also be used to obtain, a strongly typed reference to the previous page. In our example, for WebForm2, the previous page is WebForm1. So, in the HTML source of WebFOrm2.aspx paste the line below, after the Page directive.
<%
@ PreviousPageType VirtualPath="~/WebForm1.aspx" %>

In the code behind file, this.PreviousPage property or PreviousPage(without any prefix), returns a strongly typed reference to WebForm1. Please note, that Page.PreviousPage property, still returns the loosely typed Page object.
protected void Page_Load(object sender, EventArgs e)
{
   
//this.PreviousPage returns a stronly typed reference
    //WebForm1 previousPage = this.PreviousPage;
    //PreviousPage also returns a stronly typed reference
   
WebForm1 previousPage = PreviousPage;
   
//Page.PreviousPage returns loosely typed reference
    //Page previousPage = Page.PreviousPage;
   
if (previousPage != null && previousPage.IsCrossPagePostBack)
    {
       
//Access the Name and Email public properties
        lblName.Text = previousPage.Name;
        lblEmail.Text = previousPage.Email;
    }
   
else
    {
        lblStatus.Text =
"You landed on this page using a technique other than cross page post back";
    }
}

So in short to obtain a strongly typed reference, there are 2 very simple steps.
First Step – Create Public Properties (Read-Only is sufficient)
Second Step – Obtain a strongly typed reference by TypeCasting or by using the PreviousPageType directive.

Opening new window using javascript in asp.net

The following are the different page navigation techniques in asp.net
1. Hyperlink control - Discussed in
Part 13 and Part 51 of the ASP.NET video series
2. Response.Redirect - Discussed in
Part 52
3. Server.Transfer - Discussed in
Part 53
4. Server.Execute - Discussed in
Part 54
5. Cross-Page postback - Discussed in
Part 55 and Part 56
6. Window.Open

In this video we will discuss about, opening a new window using javascript method window.open(). First the syntax of the window.open() method.
window.open(URL, name, features, replace)



Parameter Name
Description
URL (Optional)
The URL of the page to open. If URL is not specified, a new window with about:blank is opened.
Name (Optional)
Specifies the target attribute or the name of the window.
  • name - The name of the window
  • _blank - Opens in a new window. Default, if nothing is specified.
  • _self - Opens in the same page
  • _parent - Loaded into the parent frame
  • _top - URL replaces any framesets that may be loaded
Features (optional)
A comma-separated list of items.
  • resizable = yes|no or 0|1
  • scrollbars = yes|no or 0|1
  • toolbar = yes|no or 0|1
  • location = yes|no or 0|1(Specifies whether to display the Navigation Bar. The default is yes)
  • status = yes|no or 0|1
  • menubar = yes|no or 0|1
  • left = yes|no or pixels
  • top = yes|no or pixels
  • width = yes|no or pixels
  • height = yes|no or pixels
Replace(Optional)
A boolean parameter that specifies whether the url creates a new entry or replaces the current entry in the window's history list. This parameter only takes effect if the url is loaded into the same window.
  • true - url replaces the current document in the history list.
  • false - url creates a new entry in the history list.



HTML of WebForm1.aspx
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Training Demo</title>
    <script type="text/javascript">
        // Javascript function to open the new window
        function OpenNewWindow()
        {
            var Name = document.getElementById('txtName').value;
            var Email = document.getElementById('txtEmail').value;
            window.open('WebForm2.aspx?Name=' + Name + '&Email=' + Email, '_blank', 'toolbar=no, location=no, resizable=yes,

width=500px, height=500px', true);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
<div style="font-family: Arial">
    <table>
        <tr>
            <td colspan="2">
                <h1>
                    This is WebForm1</h1>
            </td>
        </tr>
        <tr>
            <td>
                <b>Name</b>
            </td>
            <td>
                :<asp:TextBox ID="txtName" runat="server">
                </asp:TextBox>
            </td>
        </tr>
        <tr>
            <td>
                <b>Email</b>
            </td>
            <td>
                :<asp:TextBox ID="txtEmail" runat="server">
                </asp:TextBox>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input id="Button1" type="button" value="HTML Input Button - Window.Open"
                    onclick="OpenNewWindow()" style="width: 300px"
                />
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Button ID="Button2" runat="server"
                    Text="ASP.NET Button - Window.Open()" onclick="Button2_Click"
                    Width="300px" />
            </td>
        </tr>
        </table>
</div>
    </form>
</body>
</html>

Code-Behind code for WebForm1.aspx.cs
protected void Button2_Click(object sender, EventArgs e)
{
   
string strJavascript = "<script type='text/javascript'>window.open('WebForm2.aspx?Name=";
    strJavascript += txtName.Text +
"&Email=" + txtEmail.Text + "','_blank');</script>";
    Response.Write(strJavascript);
}

HTML of WebForm2.aspx
<div style="font-family: Arial">
    <table>
        <tr>
            <td colspan="2">
                <h1>This is WebForm2</h1>
            </td>
        </tr>
        <tr>
            <td>
                <b>Name</b>
            </td>
            <td>
                :<asp:Label ID="lblName" runat="server">
                </asp:Label>
            </td>
        </tr>
        <tr>
            <td>
                <b>Email</b>
            </td>
            <td>
                :<asp:Label ID="lblEmail" runat="server">
                </asp:Label>
            </td>
        </tr>
        </table>
</div>

Code-Behind code for WebForm2.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
    lblName.Text = Request.QueryString[
"Name"];
    lblEmail.Text = Request.QueryString[
"Email"];
}

Techniques to send data from one webform to another in in asp.net
Different techniques to move data from one webform to another 
1. Cross Page Postback: Discussed in
Part 55 and Part 56
2. Context.Handler object - Will be discuss in this video session.

The following concepts will be discussed in the subsequent sessions
3. Query strings
4. Cookies
5. Session state
6. Application state



In general, the members of one Web form are unavailable from a subsequently displayed Web form. However, when navigating between Web forms using the Transfer or Execute method, data can be retrieve from the previous Web form using Context.Handler object.

Points to remember Context.Handler object
1. Context.Handler returns WebForm1 as the previous page, only the first time when you land on WebForm2 from WebForm1. If there is a button on WebForm2, and if you click the button, the page will postback, and Context.Handler will return WebForm2 instead of WebForm1.
2. For the Context.Handler to return WebForm1 as the previous page, you should have landed on WebForm2, using Server.Transfer or Server.Execute method from WebForm1.
3. The control values from the previous page, can be accessed using FindControl() method or using public properties. The problem with FindControl() method is that, if you mis-spell the ControlID, we could get a runtime NullRefernceException. Using public properties, instead of FindControl() method, can eliminate runtime NullRefernceExceptions.
WebForm1.aspx HTML source:
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>
                This is WebForm1</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:TextBox ID="txtName" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:TextBox ID="txtEmail" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td colspan="2">
            <asp:Button ID="Button1" runat="server"
            Text="Go to WebForm2" onclick="Button1_Click" />
        </td>
    </tr>
</table>
</div>

WebForm1.aspx.cs Code:
protected void Button1_Click(object sender, EventArgs e)
{
    Server.Transfer(
"~/WebForm2.aspx");
}

public string Name
{
   
get
    {
       
return txtName.Text;
    }
}

public string Email
{
   
get
    {
       
return txtEmail.Text;
    }
}

WebForm2.aspx HTML source:
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>This is WebForm2</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:Label ID="lblName" runat="server">
            </asp:Label>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:Label ID="lblEmail" runat="server">
            </asp:Label>
        </td>
    </tr>
</table>
</div>

WebForm2.aspx.cs Code:
//On postback Context.Handler returns WebForm2
if (!IsPostBack)
{
   
Page lastpage = (Page)Context.Handler;
   
if (lastpage is WebForm1)
    {
       
//Use FindControl() if public properties does not exist on the 
        //previous page(WebForm1). FindControl() may cause 
        //NullRefernceExceptions due to mis-spelled conrol Id's

       
//lblName.Text = ((TextBox)lastpage.FindControl("txtName")).Text;
        //lblEmail.Text = ((TextBox)lastpage.FindControl("txtEmail")).Text;
                 
       
//Using public properties can eliminate NullRefernceExceptions 
        lblName.Text = ((
WebForm1)lastpage).Name;
        lblEmail.Text = ((
WebForm1)lastpage).Email;
    }
}

QueryString in asp.net
Different techniques to move data from one webform to another
1. Cross Page Postback: Discussed in
Part 55 and Part 56
2. Context.Handler object - Discussed in
Part 58
3. Query strings - Will be discussed in this session.

The following concepts will be discussed in the subsequent sessions
4. Cookies
5. Session state
6. Application state

Points to remember about query strings
1. Querystrings are name/value collection pairs
2. Using querystrings, is a very comman way to send data from one webform to another.
3. Query strings are appended to the page URL.
4. ?(Question Mark), indicates the beginning of a query string and it's value.
5. It is possible to use more than one query string. The first query string is specified using the ?(question mark). Subsequent query strings can be appended to the URL using the &(ampersand) symbol.
6. There is a limit on the Query string length. Hence, Query strings cannot be used to send very long data.
7. Query strings are visible to the user, hence should not be used to send sensitive information, unless encrypted.
8. To read the query string value, use Request object's QueryString property.
9. &(ampersand) is used to concatenate query strings, so if you want to send &, as value for the query string there are 2 ways, as shown below
Using Server.UrlEncode() method
Response.Redirect(
"WebForm2.aspx?UserName=" + Server.UrlEncode(txtName.Text) +
   
"&UserEmail=" + Server.UrlEncode(txtEmail.Text));
Or
&(ampersand) is encoded as %26, so use, Replace() function to replace & with %26
Response.Redirect(
"WebForm2.aspx?UserName=" + txtName.Text.Replace("&", "%26") +
   
"&UserEmail=" + txtEmail.Text.Replace("&", "%26"));
WebForm1.aspx HTML: We want to send Name and Email, that user enters on WebForm1.aspx to WebForm2.aspx using query strings.
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>
                This is WebForm1</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:TextBox ID="txtName" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:TextBox ID="txtEmail" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td colspan="2">
            <asp:Button ID="btnSendData" runat="server"
            Text="Go to WebForm2" onclick="btnSendData_Click" />
        </td>
    </tr>
</table>
</div>

WebForm1.aspx.cs
protected void btnSendData_Click(object sender, EventArgs e)
{
   
//Using Server.UrlEncode to encode &(ampersand)
    //Response.Redirect("WebForm2.aspx?UserName=" + Server.UrlEncode(txtName.Text) + 
    //    "&UserEmail=" + Server.UrlEncode(txtEmail.Text));
            
    //Using String.Replace() function to replace &(ampersand) with %26 
    Response.Redirect(
"WebForm2.aspx?UserName=" + txtName.Text.Replace("&", "%26") +
       
"&UserEmail=" + txtEmail.Text.Replace("&", "%26"));
}

WebForm2.aspx HTML:
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>This is WebForm2</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:Label ID="lblName" runat="server">
            </asp:Label>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:Label ID="lblEmail" runat="server">
            </asp:Label>
        </td>
    </tr>
</table>
</div>

WebForm2.aspx.cs Code:
protected void Page_Load(object sender, EventArgs e)
{
   
// Read the QueryString values 
    lblName.Text = Request.QueryString["UserName"];
    lblEmail.Text = Request.QueryString["UserEmail"];
}

Cookies in asp.net
Different techniques to send data from one webform to another 
1. Cross Page Postback:
2. Context.Handler object
3. Query strings -
4. Cookies - Will be discussed in this session

The following concepts will be discussed in the subsequent sessions
5. Session state
6. Application state

Just like QueryStrings, Cookies can also be used to send data from one webform to another. In general, web sites use cookies to store user preferences or other information that is client-specific. Cookies store small amounts of information on the client’s machine.

Cookies can be broadly classified into 2 types
1. Persistent cookies - Remain on the client computer, even after the browser is closed. You can configure how long the cookies remain using the expires property of the HttpCookie object.
2. Non-Persistent cookies - If you don't set the Expires property, then the cookie is called as a Non-Persistent cookie. Non-Persistent cookies only remain in memory until the browser is closed.

On WebForm1.aspx, user enters Name and Email. Let's write these values on to the client's computer using cookies. Finally read the values from the cookie and display them in WebForm2.aspx.



WebForm1.aspx HTML source:
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>
                This is WebForm1</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:TextBox ID="txtName" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:TextBox ID="txtEmail" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td colspan="2">
            <asp:Button ID="btnSendData" runat="server"
            Text="Go to WebForm2" onclick="btnSendData_Click" />
        </td>
    </tr>
</table>
</div>

WebForm1.aspx.cs code:
protected void btnSendData_Click(object sender, EventArgs e)
{
   
// Create the cookie object
   
HttpCookie cookie = new HttpCookie("UserDetails");
    cookie[
"Name"] = txtName.Text;
    cookie[
"Email"] = txtEmail.Text;
   
// Cookie will be persisted for 30 days
    cookie.Expires = DateTime.Now.AddDays(30);
   
// Add the cookie to the client machine
    Response.Cookies.Add(cookie);

    Response.Redirect(
"WebForm2.aspx");
}

WebForm2.aspx HTML Source:
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>This is WebForm2</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:Label ID="lblName" runat="server">
            </asp:Label>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:Label ID="lblEmail" runat="server">
            </asp:Label>
        </td>
    </tr>
</table>
</div>

WebForm2.aspx.cs Code:
protected void Page_Load(object sender, EventArgs e)
{
   
HttpCookie cookie = Request.Cookies["UserDetails"];
   
if (cookie != null)
    {
        lblName.Text = cookie[
"Name"];
        lblEmail.Text = cookie[
"Email"];
    }
}

How to Check if cookies are enabled or disabled

Different techniques to send data from one webform to another 
1. Cross Page Postback:
2. Context.Handler object -
3. Query strings
4. Cookies -

The following concepts will be discussed in the subsequent sessions
5. Session state
6. Application state

How to Check if cookies are enabled or disabled in asp.net? This is what we will discuss in this video session. Most of the articles on the internet, states we can use Request.Browser.Cookies property to check, if the cookies are enabled or disabled.
This is incorrect.
if (Request.Browser.Cookies)
{
   
//Cookies Enabled
}
else
{
   
//Cookies Disabled
}

Request.Browser.Cookies property is used to check, if the browser supports cookies. Most mordern browsers, support cookies. Irrespective of whether, the cookies are enabled or disabled, if the browser supports cookies, Request.Browser.Cookies always returns true. So use this property to check if the browser supports cookies and not to check if the cookies are enabled or disabled.
if (Request.Browser.Cookies)
{
   
//Broswer supports cookies
}
else
{
   
//Broswer does not supports cookies
}



So, the next question is, how do we check, if cookies are enabled or disabled? 
1. Write a Test Cookie
2. Redirect to the same page
3. Read the Test Cookie
4. If Cookies preseent -
Cookies are enabled
5. Else -
Cookies are disabled.

To disable cookies in Internet Explorer(IE 9)
1. Click on Tools
2. Select Internet Options
3. Click on the Privacy tab
4. Click the Advanced button, under settings
5. Check Override automatics cookie handling check box
6. Select Block radio button under First Party cookies and Third Party Cookie

The above steps disable cookies, only for the internet zone. If you are testing code on your local machine, and to disable cookies for localhost
1. Run the application
2. Press F12, to open developer tools
3. Then Select, Cache - Disable Cookies

WebForm1.aspx HTML source:
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>
                This is WebForm1</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:TextBox ID="txtName" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:TextBox ID="txtEmail" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td colspan="2">
            <asp:Button ID="btnSendData" runat="server"
            Text="Go to WebForm2" onclick="btnSendData_Click" />
        </td>
    </tr>
    <tr>
        <td colspan="2">
            <asp:Label ID="lblMessage" runat="server"
            ForeColor="Red" Font-Bold="true">
            </asp:Label>
        </td>
    </tr>
</table>
</div>

WebForm1.aspx.cs code:
protected void Page_Load(object sender, EventArgs e)
{
   
if (!IsPostBack)
    {
       
// Check if the browser supports cookies
       
if (Request.Browser.Cookies)
        {
           
if (Request.QueryString["CheckCookie"] == null)
            {
               
// Create the test cookie object
               
HttpCookie cookie = new HttpCookie("TestCookie", "1");
                Response.Cookies.Add(cookie);
               
// Redirect to the same webform
                Response.Redirect(
"WebForm1.aspx?CheckCookie=1");
            }
           
else
            {
               
//Check the existence of the test cookie
               
HttpCookie cookie = Request.Cookies["TestCookie"];
               
if (cookie == null)
                {
                    lblMessage.Text =
"We have detected that, the cookies are disabled on your browser. Please enable cookies.";
                }
            }
        }
       
else
        {
            lblMessage.Text =
"Browser doesn't support cookies. Please install one of the modern browser's that support cookies.";
        }
    }
}

protected void btnSendData_Click(object sender, EventArgs e)
{
   
// Create the cookie object
   
HttpCookie cookie = new HttpCookie("UserDetails");
    cookie[
"Name"] = txtName.Text;
    cookie[
"Email"] = txtEmail.Text;
   
// Cookie will be persisted for 30 days
    //cookie.Expires = DateTime.Now.AddDays(30);
    // Add the cookie to the client machine
    Response.Cookies.Add(cookie);

    Response.Redirect(
"WebForm2.aspx");
}

WebForm2.aspx HTML Source:
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>This is WebForm2</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:Label ID="lblName" runat="server">
            </asp:Label>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:Label ID="lblEmail" runat="server">
            </asp:Label>
        </td>
    </tr>
</table>
</div>

WebForm2.aspx.cs Code
protected void Page_Load(object sender, EventArgs e)
{
   
HttpCookie cookie = Request.Cookies["UserDetails"];
   
if (cookie != null)
    {
        lblName.Text = cookie[
"Name"];
        lblEmail.Text = cookie[
"Email"];
    }
}

Asp.net session state
Different techniques to send data from one webform to another 
1. Cross Page Postback: Discussed in
Part 55 and Part 56
2. Context.Handler object - Discussed in
Part 58
3. Query strings - Discussed in
Part 59
4. Cookies - Discussed in
Part 60 and Part 61
5. Session state - Will be discussed in this session

The following concepts will be discussed in the subsequent sessions
6. Application state

Just like Query strings, Session State variables can also be used to send data from one webform to another. 

Points to remember about session state variables:
1. Session state variables are stored on the web server by default, and are kept for the life time of a session.
2. The default session state mode is InProc. We will discuss about different session state modes in a later video session.
3. The life time of a session is determined by the timeout value in web.config file. The default is 20 minutes. The time-out value can be adjusted according, to your application requirements.
<sessionState mode="InProc" timeout="30"></sessionState>
4. Session state variables are available across all pages, but only for a given single session. Session variables are like single-user global data.
5. It is always a good practice to check, if a session state variable is null before calling any of its methods, such as ToString(). Otherwise, we may run into runtime NullReferenceExceptions.
if (Session["Name"] != null)
{
    lblName.Text = Session[
"Name"].ToString();  
}
6. Application performance can be improved by disabling session state, if it's not required. Session state can be turned off at the page or application level.

To turn of the session state at the page level, set EnableSessionState="False" in the page directive
<%@ Page Language="C#" EnableSessionState="False" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="AdoDemo.WebForm1" %>

To turn of the session state at the application level, set SessionState mode=false in web.config file.
<sessionState mode="Off"></sessionState>



WebForm1.aspx HTML source
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>
                This is WebForm1</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:TextBox ID="txtName" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:TextBox ID="txtEmail" runat="server">
            </asp:TextBox>
        </td>
    </tr>
    <tr>
        <td colspan="2">
            <asp:Button ID="btnSendData" runat="server"
            Text="Go to WebForm2" onclick="btnSendData_Click" />
        </td>
    </tr>
</table>
</div>

WebForm1.aspx.cs code:
protected void btnSendData_Click(object sender, EventArgs e)
{
    Session[
"Name"] = txtName.Text;
    Session[
"Email"] = txtEmail.Text;
    Response.Redirect(
"WebForm2.aspx");
}

WebForm2.aspx HTML Source:
<div style="font-family: Arial">
<table>
    <tr>
        <td colspan="2">
            <h1>This is WebForm2</h1>
        </td>
    </tr>
    <tr>
        <td>
            <b>Name</b>
        </td>
        <td>
            :<asp:Label ID="lblName" runat="server">
            </asp:Label>
        </td>
    </tr>
    <tr>
        <td>
            <b>Email</b>
        </td>
        <td>
            :<asp:Label ID="lblEmail" runat="server">
            </asp:Label>
        </td>
    </tr>
</table>
</div>

WebForm2.aspx.cs code:
protected void Page_Load(object sender, EventArgs e)
{
   
if (Session["Name"] != null)
    {
        lblName.Text = Session[
"Name"].ToString();  
    }
   
if (Session["Email"] != null)
    {
        lblEmail.Text = Session[
"Email"].ToString();
    }
}

Cookie less sessions in asp.net


In this session, we will discuss about cookie less sessions in asp.net. By default sessions use cookies. The session-id is stored as a cookie on the client computer. This session-id, is then, used by the web-server to identify if the request is coming from the same user or a different user.

We will be using the same example used in
Part 62, to demonstrate cookieless sessions. Run the application, and navigate to webform1.aspx. I am using google chrome as my default browser for visual studio. To set google chrome as default browser.
1. Right click on WebForm1.aspx in the solution explorer
2. Select Browse with option
3. From the list select Google chrome
4. Click "Set as Default" button
5. Finally click browse.
At this point, webform1.aspx will be opened using google chrome. Fill in the details for Name and Email fields, and click "Go To WebForm2" button. To view the session cookie
1. Right click on the browser, and select "Inspect Element"
2. Click on the "Resources" button
3. Expand cookies in the "Resources"
4. Finally, select localhost
5. You should now see a cookie with ASP.NET_SessionId
Now, let's disable cookies. To disable cookies in chrome
1. Click on the Button, next to the address bar, in the browser and select "Settings"
2. In the "Search Setting" text box, type cookies.
3. In the search results, click "content settings" button under privacy
4. Under "cookies", select "Block sites from setting any data" and click OK.

So, the cookies are disabled now. Run the application, and navigate to WebForm1.aspx. Fill name and email fields and navigate to WebForm2.aspx. Notice that the Name and Email fields are not displayed. This is because, cookies are disabled. When cookies are disabled, the session-id is not sent to the server. So the server has no way to figure out, if the request for WebForm2.aspx has come from the same user. That is the reason why these fields are not displayed on WebForm2.aspx.

Some of the users, does not like websites writing information to their computers. So it is very common for, users to disable cookies. If that is the case, then websites using cookies, to manage sessions may not work as expected. However, to overcome this problem, cookieless sessions can be enabled. To enable cookieless sessions, set cookieless="true" in web.config as shown below.
<sessionState mode="InProc" cookieless="true"></sessionState>

With this change, navigate to WebForm1.aspx, fill in Name and Email fields, and then navigate to WebForm2.aspx, and notice that, the Name and Email, fields are displayed as expected. Notice, that the session-id is now part of the URL. This session-id is sent back and forth between the client and the web server, with every request and response. The web server, uses the session-id from the URL, to identify if the request has come from the same user or a different user.

For cookieless sessions to work correctly, relative URL's must be used in the application, when redirecting users to different webforms. For example, if you are on http://pragimtech.com/WebForm1.aspx and if you want to navigate to WebForm2.aspx, then use
Response.Redirect("~/WebForm2.aspx") - Relative URL
and not
Response.Redirect("http://pragimtech.com/WebFOrm2.aspx") - Absolute URL (or Complete Path)

Inporc asp.net session state mode management
In this video, we will discuss about the asp.net session state mode - InProc. Asp.net session state mode can have any of the following 4 values. Asp.net session state mode is set in web.config file.
1. Off - Disables session state for the entire application.
2. InProc - Will be discussed in this session

The following session state modes will be discussed in a later video session.
3. StateServer
4. SQLServer
5. Custom
InProc session state mode: When the session state mode is set to InProc, the session state variables are stored on the web server memory inside the asp.net worker process. This is the default session state mode.
Advantages of InProc session state mode:
1. Very easy to implement. All that is required is, to set, the session state mode=InProc in web.config file.
2. Will perform best because the session state memory is kept on the webserver, within the ASP.NET worker process(w3wp.exe).
3. Suitable for web applications hosted on a single server.
4. Objects can be added without serialization

Dis-advantages of InProc session state mode:
1. Session state data is lost, when the worker process or application pool is recycled.
2. Not suitable for web farms and web gardens.
3. Scalability could be an issue.
Note: 
Web Garden - Web application deployed on a server with multiple processors
Web Farm - Web application deployed on multiple server  
StateServer asp.net session state mode
In this video, we will discuss about the asp.net session state mode - StateServer. Asp.net session state mode can have any of the following 4 values. Asp.net session state mode is set in web.config file.
1. Off - Disables session state for the entire application.
2. InProc - Discussed in
Part 64
3. StateServer - Will be discussed in this session.

The following session state modes will be discussed in a later video session.
4. SQLServer
5. Custom
When the session state mode is set to StateServer, the session state variables are stored in a process, called as asp.net state service. This process is different from the asp.net worker process. The asp.net state service can be present on a web server or a dedicated machine.

Steps to follow, to configure asp.net web application to use StateServer:
1. Start the ASP.NET state Service. To start the asp.net state service
    a) Click Start > Type Run > Press Enter
    b) In the run window, type services.msc and click OK.
    c) In the services window, right click on ASP.NET State Service and select Start.
2. In web.config set sessionState mode="StateServer"
3. Set stateConnectionString="tcpip=StateServer:42424"
    Example:
<sessionState mode="StateServer"     stateConnectionString="tcpip=localhost:42424"  
             
timeout="20"></sessionState>
Advantages of using StateServer session state mode:
1. ASP.NET worker process independent. Survives worker process restart.
2. Can be used with web farms and web gardens.
3. State server offers more scalability than InProc.

Dis-advantages of using StateServer session state mode:
1. StateServer is slower than InProc
2. Complex objects, need to be serialized and deserialized
3. If the StateServer, is on a dedicated machine, and if the server goes down all the sessions are lost.

Note: 
Web Garden - Web application deployed on a server with multiple processors
Web Farm - Web application deployed on multiple server 
Asp.net Application state - Part 67
Suggested Videos
Part 64 - Inporc asp.net session state mode management
Part 65 - StateServer asp.net session state mode management
Part 66 - SQLServer asp.net session state mode management

1. Application State variables are available across all pages and across all sessions. Application State variables are like multi-user global data.

2. Application State variables are stored on the web server.

3. Application State variables are cleared, only when the process hosting the application is restarted, that is when the application ends.

4. Application State variables are not shared across a Web Farm or a Web Garden.



5. Application state variables are not thread safe. Lock and Unlock methods of the application class must be used to protect against race conditions, deadlocks, and access violations.
Application.Lock();
Application[
"GlobalVariable"] = (int)Application["GlobalVariable"] + 1;
Application.UnLock();

Please Note: In this example, we are using application state variables to send data from one web form to another. If the requirement, is just to send data from webform to another, you should consider other alternatives.

6. Use application state variables only, when the variables need to have global access and when you need them for entire time, during the life time of an application. Cache object, can be used, as an alternative, if you need to have global access for a certain duration.

 Asp.net application state real time example
In this video we will discuss about a real time example, where we can use application state variables.

Application state variables are global, and all sessions have access to them. So, these variables can be used to track the number of users online. Every time a new user connects to your application, we want to increase the number of users online by 1. Along, the same lines, when ever a user session ends, then we need to decrease the number of users online by 1. But how do we know, when a new user connects to our application. Session_Start() event is fired when ever a new session is established. When the session ends, Session_End() event is fired. The event handlers are in global.asax file.



Global.asax code:
public class Global : System.Web.HttpApplication
{
   
void Application_Start(object sender, EventArgs e)
    {
       
// Code that runs when the application starts
        Application[
"UsersOnline"] = 0;
    }
    
void Session_Start(object sender, EventArgs e)
    {
       
// Code that runs when a new user session is started
        Application.Lock();
        Application[
"UsersOnline"] = (int)Application["UsersOnline"] + 1;
        Application.UnLock();
    }
    
void Session_End(object sender, EventArgs e)
    {
       
// Code that runs when an existing user session ends. 
        Application.Lock();
        Application[
"UsersOnline"] = (int)Application["UsersOnline"] - 1;
        Application.UnLock();
    }
}



The application state variable is accessible across the entire application. Copy and paste the following code in the Page_Load() event of any webform.
if (Application["UsersOnline"] != null)
{
    Response.Write(
"Number of Users Online = " +
        Application[
"UsersOnline"].ToString());
}

By default, the browser instances share the session cookie. To have a new session id assigned, when a new browser instance requests the webform, set cookieless="true" for the sessionstate element in web.config. Now run the application. The following message should be displayed.
Number of Users Online = 1

Open a new browser window, copy and paste the URL from the other window. Make sure to delete the session-id, so the web server, assigns a new session-id to the second request. At this point, Number of Users Online should be incremented to 2.


Exception handling in asp.net
In this session we will discuss about handling errors using try/catch blocks. In a later video session we will discuss about, how exceptions are generally handled in a real time asp.net application.
Exceptions are unforeseen errors that happen within the logic of an application. For example, when reading a file, a number of exception conditions can occur.
1. The file might not exist
2. You may not have permissions to access the file
When an exception occurs and if it is not handled, then, that exception is called as an, unhandled exception. An unhandled exception is displayed to the user using an "yellow screen of death". Displaying the screen of death is bad for 2 reasons
1. The error messages are cryptic and may not make any sense to the end user
2. The exception information may be useful for a hacker, to hack into your application
Exception handling using - try-catch 
try - Wrap the code in a try block that could possibly cause an exception. If a statement in the try block causes an exception, the control will be immediately transferred to the catch block.
catch - catches the exception and tries to correct the error and/or handles the exception
finally - Used to free resources. Finally block is guaranteed to execute irrespective of whether an exception has occurred or not
throw - used to raise an exception
The base class for all exceptions is the Exception class. Specific exceptions should be caught, before catching the general parent exception.
Create an asp.net web application, and add an xml file, Countries.xml. Copy and paste the following XML.
<?xml version="1.0" encoding="utf-8" ?>
<Countries>
  <Country>
    <Id>101</Id>
    <Name>India</Name>
    <Continent>Asia</Continent>
  </Country>
  <Country>
    <Id>102</Id>
    <Name>UK</Name>
    <Continent>Europe</Continent>
  </Country>
  <Country>
    <Id>103</Id>
    <Name>US</Name>
    <Continent>North America</Continent>
  </Country>
  <Country>
    <Id>104</Id>
    <Name>France</Name>
    <Continent>Europe</Continent>
  </Country>
</Countries>

Drag and drop, gridview and a lable control on WebForm1.aspx. HTML of the aspx page.
<asp:GridView ID="GridView1" runat="server">
</asp:GridView>
<br />
<asp:Label ID="lblError" Font-Bold="true" ForeColor="Red" runat="server"></asp:Label>

WebForm1.aspx.cs Code:
public partial class WebForm1 : System.Web.UI.Page
{
   
// Uncomment this line to print the name of the account 
    // used to run the application code
    // Response.Write(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
   
protected void Page_Load(object sender, EventArgs e)
    {
       
try
        {
           
DataSet ds = new DataSet();
            ds.ReadXml(Server.MapPath(
"~/Countries.xml"));
            GridView1.DataSource = ds;
            GridView1.DataBind();
        }
       
// Catch specific exceptions first
       
catch (System.UnauthorizedAccessException unauthorizedAccessException)
        {
           
//Log the exception information
            lblError.Text =
"Access to the file denied";
        }
       
catch (System.IO.FileNotFoundException fileNotFoundException)
        {
           
//Log the exception information
            lblError.Text =
"File does not exist";
        }
       
catch (Exception ex)
        {
           
//Log the exception information
            lblError.Text =
"There is an unkown problem. IT team is working on this issue. Please check back after some time";
        }
       
finally
        {
           
// Code to clean up resources like closing file handles
            // and database connection objects
        }
    }
}

Error events in asp.net
Handling exceptions using try/catch blocks is commonly termed as structured exception handling. Asp.net provide 2 error events
Page_Error - This event is raised at the page level, when there is an unhandled exception on the page. The event handler resides on the page.
Application_Error - This event is raised at the application level, when there is an unhandled exception at an application level. The event handler resides in Global.asax file
These error events can be used as a substitute or supplemental to structured exceptional handling.
Create an asp.net web application. Add a webform with name Errors.aspx. Copy and paste the following HTML in Errors.aspx.
<div style="font-family: Arial">
    <table style="border:1px solid black">
        <tr>
            <td style="color:Red">
                <h2>Application Error</h2>
            </td>
        </tr>
        <tr>
            <td>
                <h3>
                    An unkown error has occured. We are aware of it and the IT team is currently working
                    on this issue. Sorry for the inconvinience caused.</h3>
            </td>
        </tr>
        <tr>
            <td>
                <h5>
                    If you need further assistance, please contact our helpdesk at helpdesk@companyhelpdesk.com
                </h5>
            </td>
        </tr>
    </table>
</div>
Add WebForm1.aspx to the project. Drag and drop a gridview control. Copy and paste the following code in Webform1.aspx.cs.
protected void Page_Load(object sender, EventArgs e)
{
   
DataSet ds = new DataSet();
    ds.ReadXml(Server.MapPath(
"~/Data/Countries.xml"));

    GridView1.DataSource = ds;
    GridView1.DataBind();
}

protected void Page_Error(object sender, EventArgs e)
{
   
// Get the exception details and log it in the database or event viewer
   
Exception ex = Server.GetLastError();
    // Clear the exception
    Server.ClearError();
   
// Redirect user to Error page
    Response.Redirect("Errors.aspx");
}

The code tries to read xml data from Countries.xml file. At the moment, the file is not present and we get a FileNotFound exception. Since this exception is not handled using a try/catch block in the Page_Load event, the eror get to the page level and is handled by Page_Error event handler. In Page_Error event handler
1. We get the exception information using Server.GetLastError() method.
2. Do something with the exception, such as redirect the user to a generic error page, display an error message on the same page which caused the exception, try to correct the problem, or log the exception to a database table or event viewer and notify the development team. We will discuss about logging and notifications in a later video session.
3. We then clear, the exception, so that it is not get propagated to the application level.
4. Finally we redirect the user to a generic error page, Errors.aspx

Please note that 
1. If the exception is not cleared in the Page_Error event, it gets propagated to the application level, and Application_Error event handler gets executed. If we are not clearing the exception at the application level, the application crashes with the "Yellow Screen of Death".
2. If the exception is cleared and redirection to Errors.aspx is not done, then a blank page is displayed.  This is because web form processing is immediately stopped when an exception occurs.

If an exception is not handled at the page level using Page_Error event, it get's to the application level and can be handled using the Application_Error event handler in Global.asax and can be used as a single, centralized location for error handling.

Custom errors in asp.net
If there is an unhandled exception, by default, the generic yellow screen of death is displayed. Instead, custom error pages can be displayed. Custom error pages can be defined at 2 levels
1. Application Level - In the web.config file using "customErrors" element.
2. Page Level - In the Page directive, using "ErrorPage" attribute.
Page level custom error pages takes precedence over application level custom error pages.
Custom error pages provide the flexibility of displaying a specific page in response to one or more of the available HTTP status codes. For a list of all the available HTTP status please visit the following Article.
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
To specify the custom error pages at an application level, use customErrors element in web.config
<customErrors mode="On" defaultRedirect="DefaultErrorPage.aspx">
    <error statusCode="401" redirect="UnauthorizedErrorPage.aspx" />
    <error statusCode="404" redirect="PageNotFoundErrorPage.aspx" />
    <error statusCode="500" redirect="InternalServerErrorPage.aspx" />
</customErrors>
The mode attribute determines when a custom error page is displayed over the yellow screen of death, exception page. Mode attribute can have On, Off, or RemoteOnly. Default is RemoteOnly.
On - Custom error pages are displayed both on local and remote machines
Off - Custom error pages are not displayed anywhere
RemoteOnly - Custom error pages are displayed on remote machines, and exception page on local machine

If the redirection is done in Application_Error() event handler in Global.asax, custom error pages will have no effect.

In your application, if you have to display specific custom error pages for specific http status codes, then use custom errors. If you just have one generic error page, then Global.asax can be used.

Please note that, the exception object needs to be retrieved, before the user is redirected to a custom error page. Because a custom error page is displayed through redirection, the context for the error is lost and Server.GetLastError returns nothing from the target custom error page.

Windows event viewer



Exceptions in an asp.net web application can be logged to the event viewer. First let us discuss about the event viewer and create custom event log and event source. To access the event viewer
1. Click on Start
2. Type "Run" and press enter
3. In the "Run" window type "eventvwr" and press enter
4. This should open event viewer



Under windows logs, you should see
1. Application - Logs information from applications like MS Office, SQL Server, Visual Studio etc.
2. Security - Logs information related to security like user sign-ons, access checks etc
3. System - Logs information related to driver, system service failures etc.

Let us now create a windows application that can be used to create a custom windows event log and event source. The Event Source is the name of the application that logged the event. The event source is displayed in the details pane, when an event is selected in the event viewer.



Steps to create the windows application to create the custom windows event log and event source.
1. Drag and drop two textboxes, two labels, and a button control on to the windows form
2. Arrange the controls, so the form looks as shown below.

Custom Event Logs in event viewer

3. Double click the button control to generate the event handler
4. Copy and paste the following code in the click event handler
private void CreateEventLogButton_Click(object sender, EventArgs e)
{
   
if (EventLogNameTextBox.Text != string.Empty && EventLogSourceTextBox.Text != string.Empty)
    {
        System.Diagnostics.
EventLog.CreateEventSource
            (EventLogSourceTextBox.Text, EventLogNameTextBox.Text);
        MessageBox.Show(
"Event Log and Source Created");
    }
   
else
    {
        MessageBox.Show(
"Event Log and Source are required");
    }
}
5. Run the application
6. Enter the name and source for the event log.
7. Click "Create Event Log and Event Source Button" button

Open the event viewer. The newly created "event log" should be under Applications and Service Logs. If you are not able to locate them, restart your machine.

To delete the custom event log, use the Delete() method
System.Diagnostics.EventLog.Delete("EventLogNameToDelete")

Logging exceptions to the windows eventviewer - Part 73


In the previous we discussed about, creating the custom event log and event source in windows event viewer. Please watch
Windows Event Viewer - Part 72, before continuing with this session.



Create an asp.net web application project. Add WebForm1.aspx. Drag and drop girdview control. Copy and paste the following code.
//try
//{
    // DataSet is System.Data namespace
   
DataSet ds = new DataSet();
   
// This line throws FileNotFoundException
    ds.ReadXml(Server.MapPath(
"~/Data/Countries.xml"));

    GridView1.DataSource = ds;
    GridView1.DataBind();
//}
//catch (Exception ex)
//{
//    Logger.Log(ex);
//}



Add a webform with name - Errors.aspx. 
<div style="font-family: Arial">
    <table style="border:1px solid black">
        <tr>
            <td style="color:Red">
                <h2>Application Error</h2>
            </td>
        </tr>
        <tr>
            <td>
                <h3>
                    An unkown error has occured. We are aware of it and the IT team is currently working
                    on this issue. Sorry for the inconvinience caused.</h3>
            </td>
        </tr>
        <tr>
            <td>
                <h5>
                    If you need further assistance, please contact our helpdesk at helpdesk@companyhelpdesk.com
                </h5>
            </td>
        </tr>
    </table>
</div>

Add a class file with name Logger.cs
public class Logger
{
   
public static void Log(Exception exception)
    {
       
// Create an instance of StringBuilder. This class is in System.Text namespace
       
StringBuilder sbExceptionMessage = new StringBuilder();
        sbExceptionMessage.Append(
"Exception Type" + Environment.NewLine);
       
// Get the exception type
        sbExceptionMessage.Append(exception.GetType().Name);
        // Environment.NewLine writes new line character - \n
        sbExceptionMessage.Append(
Environment.NewLine + Environment.NewLine);
        sbExceptionMessage.Append(
"Message" + Environment.NewLine);
       
// Get the exception message
        sbExceptionMessage.Append(exception.Message +
Environment.NewLine + Environment.NewLine);
        sbExceptionMessage.Append(
"Stack Trace" + Environment.NewLine);
       
// Get the exception stack trace
        sbExceptionMessage.Append(exception.StackTrace +
Environment.NewLine + Environment.NewLine);

       
// Retrieve inner exception if any
       
Exception innerException = exception.InnerException;
       
// If inner exception exists
       
while (innerException != null)
        {
            sbExceptionMessage.Append(
"Exception Type" + Environment.NewLine);
            sbExceptionMessage.Append(innerException.GetType().Name);
            sbExceptionMessage.Append(
Environment.NewLine + Environment.NewLine);
            sbExceptionMessage.Append(
"Message" + Environment.NewLine);
            sbExceptionMessage.Append(innerException.Message +
Environment.NewLine + Environment.NewLine);
            sbExceptionMessage.Append(
"Stack Trace" + Environment.NewLine);
            sbExceptionMessage.Append(innerException.StackTrace +
Environment.NewLine + Environment.NewLine);

           
// Retrieve inner exception if any
            innerException = innerException.InnerException;
        }

       
// If the Event log source exists
        if (
EventLog.SourceExists("PragimTech.com"))
        {
           
// Create an instance of the eventlog
           
EventLog log = new EventLog("PragimTech");
           
// set the source for the eventlog
            log.Source =
"PragimTech.com";
           
// Write the exception details to the event log as an error
            log.WriteEntry(sbExceptionMessage.ToString(),
EventLogEntryType.Error);
        }
    }
}

Copy and pste the following code, in Global.asax, in Application_Error() event handler
if (Server.GetLastError() != null)
{
   
// Get and Log the exception
   
Logger.Log(Server.GetLastError());
   
// Clear the exception
    Server.ClearError();
   
// Transfer the user to Errors.aspx page
    Server.Transfer("Errors.aspx");
}

Run the application. WebForm1.aspx throws an exception. Since this exception is not handled any where it gets propagated till the application level, and Application_Error() event handler will be executed. This should log the exception to the windows eventviewer.

Logging exceptions as information entry type in windows eventviewer


Create an asp.net web application and add a class file with name Logger.cs.
public class Logger
{
   
public static void Log(Exception exception)
    {
        Log(exception,
EventLogEntryType.Error);
    }
   
public static void Log(Exception exception, EventLogEntryType eventLogEntryType)
    {
     
do
     {
         sbExceptionMessage.Append(
"Exception Type" + Environment.NewLine);
        sbExceptionMessage.Append(exception.GetType().Name);
         sbExceptionMessage.Append(
Environment.NewLine + Environment.NewLine);
        sbExceptionMessage.Append(
"Message" + Environment.NewLine);
         sbExceptionMessage.Append(exception.Message +
Environment.NewLine + Environment.NewLine);
        sbExceptionMessage.Append(
"Stack Trace" + Environment.NewLine);
         sbExceptionMessage.Append(exception.StackTrace +
Environment.NewLine + Environment.NewLine);

        exception = exception.InnerException;
 }
     
while (exception != null);

       
// If the Event log source exists
       
if (EventLog.SourceExists("PragimTech.com"))
        {
           
// Create an instance of the eventlog
           
EventLog log = new EventLog("PragimTech");
           
// set the source for the eventlog
            log.Source =
"PragimTech.com";
           
// Write the exception details to the event log as an error
            log.WriteEntry(sbExceptionMessage.ToString(), eventLogEntryType);
        }
    }
}



Add a webform, with name Calculator.aspx and copy the following HTML.
<div style="font-family: Arial">
    <table style="border: 1px solid black">
        <tr>
            <td><b>First Number</b></td>
            <td>
                <asp:TextBox ID="txtFirstNumber" runat="server"></asp:TextBox>
            </td>
        </tr>
        <tr>
            <td><b>Second Number</b></td>
            <td>
                <asp:TextBox ID="txtSecondNumber" runat="server"></asp:TextBox>
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Button ID="btnDivide" runat="server" Text="Divide" onclick="btnDivide_Click"
                    />
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <asp:Label ID="lblMessage" runat="server" Font-Bold="true"></asp:Label>
            </td>
        </tr>
    </table>
</div>

Calculator.aspx.cs code:
protected void btnDivide_Click(object sender, EventArgs e)
{
   
try
    {
       
int FirstNumber = Convert.ToInt32(txtFirstNumber.Text);
       
int SecondNumber = Convert.ToInt32(txtSecondNumber.Text);

        lblMessage.ForeColor = System.Drawing.
Color.Navy;
       
int Result = FirstNumber / SecondNumber;
        lblMessage.Text = Result.ToString();
    }
   
catch (FormatException formatException)
    {
       
Logger.Log(formatException, EventLogEntryType.Information);
        lblMessage.ForeColor = System.Drawing.
Color.Red;
        lblMessage.Text =
"Only numbers are allowed";
    }
   
catch (OverflowException overflowException)
    {
       
Logger.Log(overflowException, EventLogEntryType.Information);
        lblMessage.ForeColor = System.Drawing.
Color.Red;
        lblMessage.Text =
"Numbers must be between " + Int32.MinValue.ToString() + " and " + Int32.MaxValue.ToString();
    }
   
catch (DivideByZeroException divideByZeroException)
    {
       
Logger.Log(divideByZeroException, EventLogEntryType.Information);
        lblMessage.ForeColor = System.Drawing.
Color.Red;
        lblMessage.Text =
"Denominator cannot be ZERO";
    }
   
catch (Exception exception)
    {
       
Logger.Log(exception);
        lblMessage.ForeColor = System.Drawing.
Color.Red;
        lblMessage.Text =
"An unknown problem has occured. Please try later";
    }
}

FormatException, OverflowException, DivideByZeroException should now be logged as "Information" entry type instead of "Error" entry type in the event viewer.

Logging exception to database

In this we will discuss about loggin exceptions to a database table. The first step is to create the required table, to log the exceptions.

Script to create table - tblLog
Create table tblLog
(
 [Id]
int primary key identity(1,1),
 [Date]
DateTime,
 [ExceptionMessage]
nvarchar(max)
)



Stored procedure to log the exception
create procedure spInsertLog
@ExceptionMessage
nvarchar(max)
as
begin
 insert into tblLog([Date], [ExceptionMessage])
 
values (Getdate(), @ExceptionMessage)
end

Database connection string in web.config. Change it accordingly, to connect to your sql server.
<connectionStrings>
 
<add name="DBConnectionString"
 
connectionString="data source=.; database=Sample; Integrated Security=SSPI"
 
providerName="System.Data.SqlClient" />
</connectionStrings>



Add a class file with name - Logger.cs.
public class Logger
{
   
public static void Log(Exception exception)
    {
       
StringBuilder sbExceptionMessage = new StringBuilder();

       
do
        {
            sbExceptionMessage.Append(
"Exception Type" + Environment.NewLine);
            sbExceptionMessage.Append(exception.GetType().Name);
            sbExceptionMessage.Append(
Environment.NewLine + Environment.NewLine);
            sbExceptionMessage.Append(
"Message"Environment.NewLine);
            sbExceptionMessage.Append(exception.Message + 
Environment NewLine + Environment.NewLine);
            sbExceptionMessage.Append(
"Stack Trace"Environment.NewLine);
            sbExceptionMessage.Append(exception.StackTrace + 
Environment NewLine + Environment.NewLine);

            exception = exception.InnerException;
        }
       
while (exception != null);
     
        LogToDB(sbExceptionMessage.ToString());
    }

   
private static void LogToDB(string log)
    {
       
// ConfigurationManager class is in System.Configuration namespace
       
string connectionString = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
       
// SqlConnection is in System.Data.SqlClient namespace
       
using (SqlConnection con = new SqlConnection(connectionString))
        {
           
SqlCommand cmd = new SqlCommand("spInsertLog", con);
           
// CommandType is in System.Data namespace
            cmd.CommandType =
CommandType.StoredProcedure;

           
SqlParameter parameter = new SqlParameter("@ExceptionMessage", log);
            cmd.Parameters.Add(parameter);

            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
        }
    }
}

Add a webform with name - Errors.aspx.
<div style="font-family: Arial">
    <table style="border:1px solid black">
        <tr>
            <td style="color:Red">
                <h2>Application Error</h2>
            </td>
        </tr>
        <tr>
            <td>
                <h3>
                    An unkown error has occured. We are aware of it and the IT team is currently working
                    on this issue. Sorry for the inconvinience caused.</h3>
            </td>
        </tr>
        <tr>
            <td>
                <h5>
                    If you need further assistance, please contact our helpdesk at helpdesk@companyhelpdesk.com
                </h5>
            </td>
        </tr>
    </table>
</div>

Add a webform to the project. Drag and drop a gridview control. Copy and paste the following code in the code behind file, in the Page_Load() event.
//try
//{
    // DataSet is in System.Data namespace
   
DataSet ds = new DataSet();
   
// This line will throw an exception, as Data.xml 
    // file is not present in the project
    ds.ReadXml(Server.MapPath(
"~/Data.xml"));
    GridView1.DataSource = ds;
    GridView1.DataBind();
//}
//catch (Exception ex)
//{
//    Logger.Log(ex);
//    Server.Transfer("~/Errors.aspx");
//}

Global.asax code:
void Application_Error(object sender, EventArgs e)
{
   
if (Server.GetLastError() != null)
    {
        // Log the exception
       
Logger.Log(Server.GetLastError());
        // Clear the exception
        Server.ClearError();
       
// Transfer the user to Errors.aspx page
        Server.Transfer(
"Errors.aspx");
    }
}

Run the application. The exception should be logged to the Database table - tblLog and the user will be redirected to Errors.aspx page.



Customizing asp.net exception

In this we will discuss about logging exception to both
1. A database table
2. Windows eventviewer

The ability to log exceptions must be configurable in web.config
Add a key to web.config file using appsettings element. This key determines, where the exceptions are logged.
<appSettings>
 
<!--LogProvider = Database|EventViewer|Both-->
 
<add key="LogProvider" value="Both"/>
</appSettings>

The "Logger" class reads the "LogProvider" key from web.config and logs the exceptions accordingly.



public class Logger
{
   
public static void Log(Exception exception)
    {
       
StringBuilder sbExceptionMessage = new StringBuilder();

       
do
        {
            sbExceptionMessage.Append(
"Exception Type" + Environment.NewLine);
            sbExceptionMessage.Append(exception.GetType().Name);
            sbExceptionMessage.Append(
Environment.NewLine + Environment.NewLine);
            sbExceptionMessage.Append(
"Message"Environment.NewLine);
            sbExceptionMessage.Append(exception.Message + 
Environment NewLine + Environment.NewLine);
            sbExceptionMessage.Append(
"Stack Trace"Environment.NewLine);
            sbExceptionMessage.Append(exception.StackTrace + 
Environment NewLine + Environment.NewLine);

            exception = exception.InnerException;
        }
       
while (exception != null);

       
string logProvider = ConfigurationManager.AppSettings["LogProvider"];
       
if (logProvider.ToLower() == "both")
        {
            LogToDB(sbExceptionMessage.ToString());
            LogToEventViewer(sbExceptionMessage.ToString());
        }
       
else if (logProvider.ToLower() == "database")
        {
            LogToDB(sbExceptionMessage.ToString());
        }
       
else if (logProvider.ToLower() == "eventviewer")
        {
            LogToEventViewer(sbExceptionMessage.ToString());
        }
    }

   
private static void LogToDB(string log)
    {
       
// ConfigurationManager class is in System.Configuration namespace
       
string connectionString = ConfigurationManager.ConnectionStrings["DBConnectionString"].ConnectionString;
       
// SqlConnection is in System.Data.SqlClient namespace
       
using (SqlConnection con = new SqlConnection(connectionString))
        {
           
SqlCommand cmd = new SqlCommand("spInsertLog", con);
           
// CommandType is in System.Data namespace
            cmd.CommandType =
CommandType.StoredProcedure;

           
SqlParameter parameter = new SqlParameter("@ExceptionMessage", log);
            cmd.Parameters.Add(parameter);

            con.Open();
            cmd.ExecuteNonQuery();
            con.Close();
        }
    }

   
private static void LogToEventViewer(string log)
    {
       
if (EventLog.SourceExists("PragimTech.com"))
        {
           
// Create an instance of the eventlog
           
EventLog eventLog = new EventLog("PragimTech");
           
// set the source for the eventlog
            eventLog.Source =
"PragimTech.com";
           
// Write the exception details to the event log as an error
            eventLog.WriteEntry(log,
EventLogEntryType.Error);
        }
    }
}

Global.asax, Errors.aspx and WebForm1.aspx HTML and code have not changed from
Part 75 - Logging exception to database.

No comments:

Post a Comment