Sunday, 9 December 2012

Advanced ASP NET Server Controls

Goals:
  • Present advanced ASP.NET server controls (data display controls are not included here).
Steps:
  1. Create a new ASP.NET Web Application project in Visual Studio.
  2. Table
    • The Table control is a useful way to dynamically generate or modify a table. The Table's content can be easily created using the Designer:
    • Content of the table can be dynamically modified also:
      protected void Page_Load(object sender, EventArgs e)
      {
          
      if (!IsPostBack)
          {
              Table1.Rows[1].Cells.RemoveAt(2);
              Table1.Rows[1].Cells[0].HorizontalAlign =
      HorizontalAlign.Center;
              Table1.Rows[1].Cells[0].ColumnSpan = 2;

              
      TableRow tr = new TableRow();
              Table1.Rows.Add(tr);

              
      TableCell tc = new TableCell();
              tc.Text =
      "Seventh";
              tr.Cells.Add(tc);

              tc =
      new TableCell();
              tc.Text =
      "Eight";
              tr.Cells.Add(tc);

              tc =
      new TableCell();
              tc.Text =
      "Ninth";
              tr.Cells.Add(tc);
          }
      }
  3. Calendar
    • It is a quite functional control for presenting a calendar to the user.

      Take a look at the generated HTML code to see how many HTML code is necessary to render the calendar.
      Note, that changing a month causes a postback. Unfortunately, this is a limitation of this control. The user's inconvenience can be reduced using AJAX, but for the most demanding users other Calendar control must be used.
    • Selecting a day causes the SelectionChange event:
      protected void Calendar1_SelectionChanged(object sender, EventArgs e)
      {
          Literal7.Text =
      "Selected day: " + Calendar1.SelectedDate.ToString();
      }
  4. AdRotator
    • This is an interesting control which allows to display advertisements to the page.
    • It is based on an XML file containing data of advertisements. Add to the project a new XML file, named Ads.xml, placed in the App_Data folder. Put the following sample content into this file:
      <?xml version="1.0" encoding="utf-8" ?>
      <
      Advertisements>
          <
      Ad>
              <
      ImageUrl>~/Images/1st.jpg</ImageUrl>
              <
      NavigateUrl>http://www.1st.com</NavigateUrl>
              <
      AlternateText>1st</AlternateText>
              <
      Impressions>10</Impressions>
              <
      Keyword></Keyword>
          </
      Ad>
          <
      Ad>
              <
      ImageUrl>~/Images/2nd.jpg</ImageUrl>
              <
      NavigateUrl>http://www.2nd.com</NavigateUrl>
              <
      AlternateText>2nd</AlternateText>
              <
      Impressions>10</Impressions>
              <
      Keyword></Keyword>
          </
      Ad>
          <
      Ad>
              <
      ImageUrl>~/Images/3rd.jpg</ImageUrl>
              <
      NavigateUrl>http://www.3rd.com</NavigateUrl>
              <
      AlternateText>3rd</AlternateText>
              <
      Impressions>10</Impressions>
              <
      Keyword></Keyword>
          </
      Ad>
      </
      Advertisements>
      In this content we assume, that 3 graphics files: 1st.jpg, 2nd.jpg, and 3rd.jpg are located in the Images subfolder.
    • Add the AdRotator control to the page. Click on it '>' small button to open the 'AdRotator Tasks' window, choose an item to create a new Data Source, choose the 'XML File' as a category and point the App_Data/Ads.xml file.

      Note, that a new component of the XmlDataSource type was created automatically.
    • Run the page, refresh it many times in a browser and note that the displayed image changes.
  5. FileUpload
    • The FileUpload control allows in a very easy way to manage a file sent by the user using standard HTML <input type="file"> mechanism.
    • Add the FileUpload control, a Button, and a Literal (the Button is needed to make send action, the Literal is used only for showing some information about the sent file):
    • The sent file must be saved manually, fortunately the FileUpload control has the SaveAs method:
      protected void Button1_Click(object sender, EventArgs e)
      {
          
      if (FileUpload1.HasFile)
          {
              
      try
              {
                  
      string destPath = Server.MapPath("~/App_Data/" + FileUpload1.FileName);
                  FileUpload1.SaveAs(destPath);

                  Literal8.Text =
      string.Format("File name: {0} <br>Size: {1} <br>Content type: {2}",
                      FileUpload1.PostedFile.FileName,
                      FileUpload1.PostedFile.ContentLength,
                      FileUpload1.PostedFile.ContentType);
              }
              
      catch (Exception ex)
              {
                  Literal8.Text =
      "ERROR: " + ex.Message.ToString();
              }
          }
          
      else
          {
              Literal8.Text =
      "No file to send.";
          }
      }
  6. Panel
    • The Panel control provides a container within the page for other controls. It allows to show and hide all contained controls, change their attributes, scroll the content, change the horizontal alignment, and set a background image. See the following example:

      protected void Button2_Click(object sender, EventArgs e)
      {
          Panel1.Visible =
      false;
      }
  7. MultiView, View
    • The MultiView and View server controls work together to enable the capability to turn on/off sections of an ASP.NET page. As an example, add the MultiView control with 3 View controls and add some controls to these Views. Add also a button which will allow to display the next view:
      <asp:MultiView ID="MultiView1" runat="server">
          <asp:View ID="View1" runat="server">
              <asp:Image ID="Image1" runat="server" ImageUrl="Images/1st.jpg" />     </asp:View>
          <asp:View ID="View2" runat="server">
              <asp:Image ID="Image2" runat="server" ImageUrl="Images/2nd.jpg" />     </asp:View>
          <asp:View ID="View3" runat="server">
              <asp:Image ID="Image3" runat="server" ImageUrl="Images/3rd.jpg" />     </asp:View>
      </
      asp:MultiView>
      <
      asp:Button ID="Button3" runat="server" Text="Next view >>"
          
      onclick="Button3_Click" />
       
      protected void Page_Load(object sender, EventArgs e)
      {
          
      if (!IsPostBack)
          {
              MultiView1.ActiveViewIndex = 0;
          }
      }
      protected void Button3_Click(object sender, EventArgs e)
      {
          
      if (MultiView1.ActiveViewIndex < MultiView1.Views.Count - 1)
          {
              MultiView1.ActiveViewIndex++;
          }
      }
  8. Wizard
    • The Wizard control can be used when there is a need for step-by-step logic. This control allows for a far greater degree of customization than does the MultiView control. As an example add the Wizard control and add some controls to its steps:
    • This control has some interesting events, e.g. FinishButtonClick:
      protected void Wizard1_FinishButtonClick(object sender, WizardNavigationEventArgs e)
      {
          Wizard1.Visible =
      false;
          Literal1.Visible =
      true;
      }
    • There are many formatting options available for the Wizard button. The easiest way is probably to start from the AutoFormat option:
  9. PlaceHolder
    • This control is a placeholder to interject objects dynamically into the Web page. It does not produce any visible output and is only used as a container for other controls on the Web page. Its Controls collection can be used as for any container.

      protected void Button4_Click(object sender, EventArgs e)
      {
          
      Literal literal = new Literal();
          literal.Text =
      string.Format("{0}<br>", DateTime.Now.ToString());
          PlaceHolder1.Controls.Add(literal);
      }

      Run the page. Note that after clicking the 'Add a Literal to the PlaceHolder' button, a new Literal appears in the place reserved by the PlaceHolder. Note also that after the second clicking on the button, the previously added text disappears. The reason of this behaviour is simple - each time the request is processed by the ASP.NET engine, the PlaceHolder control (as any other control) is initialized. Initialization of the PlaceHolder control used in this example does nothing - no controls are added to it. Later, after initialization and loading, the event handler adds one control, and this is the only one visible control.
  10. HiddenField
    • This control can be used to store some data at the level of a single page. For example, it can be used to solve the problem from the previous point - to allow to display all values added to the PlaceHolder control.
    • Add the HiddenField control to the page. (The place does not matter - the control is invisible.)
      <asp:HiddenField ID="HiddenField1" runat="server" />
    • Modify code in the Load event of the page and the Click event of the button:
      protected void Page_Load(object sender, EventArgs e)
      {
          
      if (!IsPostBack)
          {
              
      // previous code    }
          
      else
          {
              
      string[] texts = HiddenField1.Value.Split(';');
              
      foreach (string text in texts)
              {
                  AddToPlaceHolder(text);
              }
          }
      }
      private void AddToPlaceHolder(string text)
      {
          
      Literal literal = new Literal();
          literal.Text = text +
      "<br>";
          PlaceHolder1.Controls.Add(literal);
      }
      private void AddToHiddenField(string text)
      {
          
      if (HiddenField1.Value.Length > 0)
          {
              HiddenField1.Value +=
      ';';
          }
          HiddenField1.Value += text;
      }
      protected void Button4_Click(object sender, EventArgs e)
      {
          
      string text = DateTime.Now.ToString();
          AddToPlaceHolder(text);
          AddToHiddenField(text);
      }
      Run the page and make a few postbacks using the Button4, note that values in the PlaceHolder control are kept.
    • Very common usage of the HiddenField control is passing data from the server to the client-side code written in JavaScript and vice-versa.
[Source code]

ASP.NET Server Controls

Goals:
  • Present simple ASP.NET server controls.
Steps:
  1. Create a new ASP.NET Web Application project in Visual Studio.
  2. Label
    • Add a Label control to the page, modify its Text property.
    • Run the application and take a look at the source code of generated HTML code, note that the Label control was rendered as the span tag:
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      
      <html xmlns="http://www.w3.org/1999/xhtml" >
      <head><title>
      
      </title></head>
      <body>
          <form name="form1" method="post" action="Default.aspx" id="form1">
      <div>
      <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUJOTczNTMyNjI5ZGQ+tlIH8gC3zZwd0romTjnrPAqrbg==" />
      </div>
          <div>
              <span id="Label1">This is a label</span>
          </div>
          </form>
      </body>
      </html>
    • An interesting feature of the Label control is ability to define a hot-key for an assigned server control. Add Label and TextBox controls to the page and set the AccessKey and AssociatedControlID properties of the Label:
    • This time, the rendered HTML code contains the Label tag:
          <label for="TextBox1" id="Label2" accesskey="T">
              Label associated with <u>T</u>extBox (use Alt+T to move the focus to 
              the TextBox)
          </label>
          <input name="TextBox1" type="text" id="TextBox1" />
  3. Literal
    • The Literal control is similar to the Label control, but it is rendered as a plain text, without additional tags. Add 2 Literal controls to the page and set their Text property to 'Normal text, <b>bold</b> text'. For the second control set also the Mode property to 'Encode':
    • Check the output HTML code, note the difference in rendering '<' and '>' characters:
       Normal text, <b>bold</b> text.
      <br />
      Normal text, &lt;b&gt;bold&lt;/b&gt; text.
  4. TextBox
    • Add 3 TextBox controls to the page. Leave the first one default. Set the TextMode property of the 2nd one to 'Password'. Set the TextMode property of the 3rd one to 'MultiLine' and set also its Width and Height properties:
    • Look at the generated HTML code and note differences:
       Simple textbox:
      <input name="TextBox2" type="text" id="TextBox2" />
      <br />
      Password textbox:
      <input name="TextBox3" type="password" id="TextBox3" />
      <br />
      Multiline textbox:
      <textarea name="TextBox4" rows="2" cols="20" id="TextBox4" style="height:100px;width:200px;"></textarea>
    • The TextBox control has the TextChanged event triggered when the user moves the focus outside the text box. Add an event handler for this event to the TextBox, in response for this event modify the control's text:
      protected void TextBox2_TextChanged(object sender, EventArgs e)
      {
          TextBox2.Text +=
      " --- MODIFIED!";
      }
    • To make it work, the AutoPostBack property of the TextBox must be changed to true.
    • Run and test the page. Note that the postback is sent when the focus leaves the text box.
    • It is also possible to do something dynamically without a postback, using JavaScript. Add the following code to the page (e.g. between the header and the body of the page):
      <script>
      function
      tbChangedJS() {
          
      return confirm("Should I postback?");
      }
      </script>
      For the TextBox, add the onchange property with JavaScript code calling this method:
      <asp:TextBox ID="TextBox2" runat="server" AutoPostBack="True"
          
      ontextchanged="TextBox2_TextChanged"
          onchange="if (!tbChangedJS()) return;" >
      </
      asp:TextBox>
      To understand how it works, see the output HTML code:
      <input name="TextBox2" 
             type="text" 
             onchange="if (!tbChangedJS()) return;setTimeout('__doPostBack(\'TextBox2\',\'\')', 0)" 
             onkeypress="if (WebForm_TextBoxKeyHandler(event) == false) return false;" 
             id="TextBox2" />
      Note that the default TextBox's rendering adds some JavaScript code.
  5. Button
    • Add the Button controls to the page, and double-click it in the Design view - the onclick event is automatically generated:

      Add code modifying the Button's text in response for this event:
      protected void Button1_Click(object sender, EventArgs e)
      {
          Button1.Text +=
      " - clicked!";
      }
      Compile and test the page.
    • It is also possible to fire the JavaScript click event before the postback, add the following code to the Button1:
      onclientclick="alert('Hello from the Button1');"
    • It is possible to attach one common ASP.NET click event handler to more than 1 button. Add 2 new buttons and a Literal to the page:
      <asp:Button ID="Button2" Runat="server" Text="Button 2"
          
      OnCommand="Button_Command" CommandName="DoSomething2" />
      <
      asp:Button ID="Button3" Runat="server" Text="Button 3"    OnCommand="Button_Command" CommandName="DoSomething3" />
      <
      asp:Literal ID="Literal3" Runat="server"/>
      Add the following code to the code-behind file:
      protected void Button_Command(Object sender, CommandEventArgs e)
      {
          
      switch (e.CommandName)
          {
              
      case "DoSomething2":
                  Literal3.Text =
      "Button 2 was selected";
                  
      break;
              
      case "DoSomething3":
                  Literal3.Text =
      "Button 3 was selected";
                  
      break;
          }
      }
  6. LinkButton
    • The LinkButton control is a button rendered as a hyperlink:
  7. ImageButton
    • The ImageButton control has all the Button's functionality plus possibility to check coordinates of clicked point. Add the following markup code:
      <asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="sample.jpg"
          
      onclick="ImageButton1_Click" />
      <
      asp:Literal ID="Literal4" runat="server"></asp:Literal>
      and C# code:
      protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
      {
          Literal4.Text =
      string.Format("Click at ({0}, {1})", e.X, e.Y);
      }
  8. HyperLink
    • Hyperlinks generated by the HyperLink control can use text or image:
    • This control is rendered as a <a> tag:
       <a id="HyperLink1" href="http://www.google.com">HyperLink to google</a>
      <br />
      <a id="HyperLink2" href="http://www.google.com"><img src="sample.gif" style="border-width:0px;" /></a>
  9. DropDownList
    • Items of the DropDownList control can be initialized statically (the Visual Studio Designer can be used for the Items property, instead of manual writing values):
    • Additionally, the content can be modified dynamically (Default.aspx.cs file):
      protected void Page_Load(object sender, EventArgs e)
      {
          
      if (!IsPostBack)
          {
              DropDownList1.Items.Remove(
      "Second");
              DropDownList1.Items.Add(
      "Fourth");
              DropDownList1.SelectedValue =
      "Third";
          }
      }
      To understand, why checking of the IsPostBack flag is necessary, comment it out, run the page and make some postbacks using other controls - the Fourth item will appear many times on the list.
    • The DropDownList control automatically forces a postback in case of changing its selected value, when the AutoPostBack property is set to true:
      AutoPostBack="True" onselectedindexchanged="DropDownList1_SelectedIndexChanged"
      Code for the event:
      protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
      {
          DropDownList1.SelectedItem.Text +=
      " - selected!";
      }
  10. ListBox
    • The ListBox control has similar functionality to the DropDownList control, but additionally more than one item can be selected when the SelectionMode property is set to 'Multiple':

      protected void Button4_Click(object sender, EventArgs e)
      {
          
      StringBuilder sb = new StringBuilder("Selected: ");
          
      foreach (int i in ListBox1.GetSelectedIndices())
          {
              sb.AppendFormat(
      "{0} ", ListBox1.Items[i].Text);
          }
          Literal5.Text = sb.ToString();
      }
  11. CheckBox
    • The CheckBox control can also force a postback, when the AutoPostBack property is set to true. Additionally, text alignment can be changed:

      protected void CheckBox1_CheckedChanged(object sender, EventArgs e)
      {
          CheckBox1.Text +=
      " - checked!";
      }
  12. CheckBoxList
    • This control is very helpful when there is a need to display a list of items with checkboxes to allow to select presented items. Instead of creating many CheckBox controls, one CheckBoxList control can be used:
    • Items can be added using the Items property (either statically in the Visual Studio Designer or dynamically in the source code), or bound using the DataSource property:
      protected void Page_Load(object sender, EventArgs e)
      {
          
      if (!IsPostBack)
          {
              DropDownList1.Items.Remove(
      "Second");
              DropDownList1.Items.Add(
      "Fourth");
              DropDownList1.SelectedValue =
      "Third";

              
      string[] items = new string[] { "First", "Second", "Third", "Fourth", "Fifth" };
              CheckBoxList1.DataSource = items;
              CheckBoxList1.DataBind();
          }
      }
      protected void Button5_Click(object sender, EventArgs e)
      {
          StringBuilder sb = new StringBuilder("Selected: ");
          foreach (ListItem li in CheckBoxList1.Items)
          {
              if (li.Selected)
              {
                  sb.AppendFormat("{0} ", li.Text);
              }
          }
          Literal6.Text = sb.ToString();
      }
      Setting the DataSource property does not makes the action of binding data, the DataBind method must be called explicitly.
  13. RadioButton
    • For the RadioButton controls the GroupName property is crucial. For example, in the following code the 1st and 2nd RadioButton controls can be selected simultaneously because their values of the GroupName property differ:
  14. RadioButtonList
    • This control is very similar to the CheckBoxList control, the only difference is that in the RadioButtonList it is impossible to select more than 1 item.
  15. BulletedList  
    • The BulletedList control can be an alternative for the RadioButtonList control. It can display a list of items:

      and catch a click on an item:
      protected void BulletedList1_Click(object sender, BulletedListEventArgs e)
      {
          Literal7.Text =
      "Clicked: " + BulletedList1.Items[e.Index].Text;
      }
  16. Image
    • The Image control is rendered as a static image, which does not support handling user clicks.
  17. ImageMap
    • It enables to turn an image into a navigation menu. Rectangle, circle, and polygon hotspots (easy to define using the Visual Studio Designer) can be used to catch clicks. In the following example one rectangle (pointing to http://www.google.com ) and one circle hotspot (causes a postback) are used:

      Note, that the red circle and rectangle are statically drawn on the image.
      protected void ImageMap1_Click(object sender, ImageMapEventArgs e)
      {
          
      if (e.PostBackValue == "theCircle")
          {
              Literal8.Text =
      "Circle clicked!";
          }
      }
[Source code]

Introduction about ASP.Net Application and Pages

Goals:
  • Present main concepts of the ASP.NET applications.
  • Introduce web pages and their events.
Steps:
  1. Create a new project - Visual C# / Web / ASP.NET Web Application.
    There is also possibility to create a 'Web Site' (menu File / New / Web Site), but the 'Web Application' should be preferred. The Web Site has no project file. The lack of a project file can make the application's configuration much harder (sometimes even impossible)
  2. Take a look into the generated project.
    • The AssemblyInfo.cs file, as usually in .NET C# projects, contains definition of the project assembly's properties.
    • The App_Data item is a folder, where all data files used by the project should be kept, e.g. text, xml, or database files. This folder is configured in a special way by default - the user account that is used to run the application (for example, the local ASP.NET account) has permissions to read, write, and create files in this folder.
    • The Default item is a web page (aka 'web form'). There are 3 files generated as parts of this item:
      • Default.aspx contains the design of a web page. All the HTML and ASP.NET tags are placed here (unless some of they are generated dynamically in the source code). There are 2 different views for editing this file: 'Design' and 'Source'. In the Design mode all the design can be visually modified, and in the Source mode you can manually modify all tags. There is also the 'Split' mode which allows to use the Design and Source modes simultaneously.
        The visual designer of ASP.NET pages built in Visual Studio (i.e. the Design mode) is a quite comfortable and powerful visual editor for HTML files, in fact.
      • Default.aspx.cs is so called code-behind file, it contains C# source code for the page. Usually, the code file contains methods responding for the page's or its controls events and some helpful methods.
      • Default.aspx.designer.cs contains C# code generated by the Visual Studio in response for modification of the .aspx file. In example, after adding a control to the .aspx file, a member of the page's class representing this control will be automatically added to this file.
    • The Web.config file is a configuration file of the web application. There are many web-related configuration options allowed to be placed here. This file serves also as a normal configuration file for the .NET project, just like .exe.config files for Windows Forms or console projects.
  3. Add text to the Default page:
  4. Run the project (Ctrl+F5 or menu Debug / Start Without Debugging). Note the following actions:
    • Visual Studio compiles the project.
    • The ASP.NET Development Server is started in the system:
    • The default Internet browser starts and opens the address: http://localhost:49691 (the port number can vary):
    • Take a look into source code of the generated page (use the 'View Source Code' option in the browser):
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      
      <html xmlns="http://www.w3.org/1999/xhtml" >
      <head><title>
      
      </title></head>
      <body>
          <form name="form1" method="post" action="Default.aspx" id="form1">
      <div>
      <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZO/ZMzP2K7pbdL0x/efEBPI9tp28" />
      </div>
      
          <div>
          
              Welcome on the Default page.</div>
      
          </form>
      </body>
      </html>
      Compare this code with source code of the Default.aspx file in Visual Studio and note some differences - ASP.NET automatically generates the output HTML code based on the source ASP.NET code. For most complicated pages using some ASP.NET controls there will be more differences.
  5. Modify in Visual Studio the text displayed on the page and save the file. Do not compile the project, just refresh the page in the browser. Note that the text has changed. ASP.NET automatically checks for changes in source code files and, when there is such need, recompiles the project.
  6. Add a new Web Form to the project (right click on the project in the Solution Explorer window: Add / New Item / Web Form). Name it Info.aspx:
    • Add the following code to the Page_Load method in the Info.aspx.cs file:
      Response.Write(string.Format("ApplicationPath: {0}<br>", Request.ApplicationPath));
      Response.Write(
      string.Format("CurrentExecutionFilePath: {0}<br>", Request.CurrentExecutionFilePath));
      Response.Write(
      string.Format("FilePath: {0}<br>", Request.FilePath));
      Response.Write(
      string.Format("Path: {0}<br>", Request.Path));
      Response.Write(
      string.Format("PhysicalApplicationPath: {0}<br>", Request.PhysicalApplicationPath));
      Response.Write(
      string.Format("ApplicationPath: {0}<br>", Request.ApplicationPath));
      Response.Write(
      "<br><br>");
      Response.Write(
      string.Format("Physical ~ is {0}<br>", Server.MapPath("~")));
      • The Page_Load method is automatically attached to the Load event of the page. The AutoEventWireup property of the Page declaration starting the Info.aspx file is responsible for this.
      • The Response object used in the C# code is a property of the current page. (All the code in the .aspx.cs file is a part of the page's class, so all its properties are directly available.) The Write method allows to directly generate the output HTML code. (This is very powerful possibility but should not be overused in conjunction with using ASP.NET controls.)
      • The Request is also a property of the current page. It represents the request coming from the user's browser. It makes available some very useful properties, in example these used in the above code.
      • The '~' character in logical paths always represents the main folder of the application. It is used in logical web paths, not in physical disk ones.
      • To convert logical web path to physical disk path, the MapPath method of the HttpServerUtility class can be used. An object of this class is available as the Server property of the current page.
    • Run the application (Ctrl+F5):
    • Make the Default.aspx page the starting one (right click on the page in the Solution Explorer window: Set as Start Page).
  7. Add to the Default.aspx page options that will allow to move to the Info.aspx page (currently, the only option is manual modification of the address displayed in the browser). There are a few ways to do it:
    • The 1st way is to add a simple HTML hyperlink to the Default.aspx file:

      Note, a relative path (i.e. no path - both files are in the same directory) was used. It is always a good idea to avoid hard-coding absolute paths).
    • The 2nd way is to use ASP.NET control that works like an HTML hyperlink. Drop to the Default.aspx design a Hyperlink control dragged from the Standard group from the Toolbox window.
    • The 3rd way is to force the user's browser to ask for another page. This can be done only in response for a request from the browser. To get a request, a button will be used.
      • Drop on the Default.aspx design a Button control (from the Toolbox):
      • Double click the button to generate a handler for its Click event. Add the following code to the handler:
        protected void Button1_Click(object sender, EventArgs e)
        {
            Response.Redirect(
        "Info.aspx");
        }
      • Note that in this way one additional transmission from the server to the client and back is required, so, in most cases, such solution makes sense only when redirection is done to another application or server. Such redirections within a single web application are extremely inefficient.
    • Another way is transferring requests within a single web application. This can be using the Transfer method of the HttpServerUtility class.
      • Add a button like in the previous solution:
      • Add the following code in the Click event handler:
        protected void Button2_Click(object sender, EventArgs e)
        {
            Server.Transfer(
        "Info.aspx");
        }
      • This solution is definitely more efficient than the previous one (no additional round trip of a request/response pair is necessary), but there are some drawbacks
        • The user will see in the browser the address of the Default.aspx page, but the content of the Info.aspx file:
        • The Transfer method throws ThreadAbortException to abort processing of the original request (for the Default.aspx page, in this example).
    • Yet another way is using so-called cross-page posting. Normally, all controls post back to the same page (that's why the C# code for responding for Click event for the above buttons was located on the Default.aspx page). Cross-page posting consists in specifying another page as a target for, in example, clicking a button.
      • Add a button to the Default.aspx page and set its PostBackUrl property to Info.aspx:
  8. Test some of web pages' events:
    • Add a new Web Form to the project.
    • Add the following code to the .aspx.cs file:
      Button dynamicButton;
      protected override void OnInit(EventArgs e)
      {
          Response.Write(
      "=== Init event ===<br>");
          
      base.OnInit(e);

          dynamicButton =
      new Button();
          dynamicButton.Text =
      "Dynamic button";
          dynamicButton.Click +=
      new EventHandler(DynamicButton_Click);
          Form.Controls.Add(dynamicButton);
      }
      void DynamicButton_Click(object sender, EventArgs e)
      {
          Response.Write(
      "=== DynamicButton_Click event ===<br>");
      }
      protected override void OnLoad(EventArgs e)
      {
          Response.Write(
      "=== Load event ===<br>");
          
      base.OnLoad(e);
      }
      protected override void OnPreRender(EventArgs e)
      {
          Response.Write(
      "=== PreRender event ===<br>");
          
      base.OnPreRender(e);

          dynamicButton.OnClientClick =
      "alert('Hello from Dynamic Button')";
      }
    • Run the application and test how it works:
    • In this code instead of the Page_Load method, the OnLoad overridden method was used. In both cases the result is the same - code from these methods is executed during the Load event. The OnLoad method should be preferred, because the Page_Load method is based on the mechanism of 'wiring' automatically methods to events by their names, which is slower than direct overriding methods.
    • Only controls added to the page's Form property (or contained within the <form> tag) will be rendered to the output HTML code. This is the reason of calling the Form.Controls.Add method.
    • The OnClientClick property of a button can contain JavaScript code to be executed in the user's browser.
  9. The source code of the web application can be debugged. It concerns both the C# and JavaScript code. The support for debugging is not limited to the Internet Explorer browser.
    To debug the application just press F5 button in Visual Studio. If it is the first try of debugging, a message appears:

    Note that (as mentioned in the message) enabling debugging should be disabled before deploying the application to the production server.
  10. Apart from the page's and its controls' events, there are also application's events available. There are only a few of application's events, but some of them can be extremely useful.
    • Add to the project the Global Application Class:
    • Add to the Application_Start method in the Global.asax file the following line:
      Application["StartTime"] = DateTime.Now;
      This line allows to store time of the beginning of the application in the dictionary of values shared by all pages of the application.
    • Add to the Page_Load method of the Info.aspx page the following line:
      Response.Write(string.Format("Application[\"StartTime\"]: {0}<br>", Application["StartTime"]));
    • Run the application, refresh the Info.aspx page many times and note that the value of 'StartTime' does not change. Rebuild the application, refresh the Info.aspx in the browser and note a new value. It proves that rebuilding the source code causes restart of the application.
[Source code]

Image without using Generic Handler in ASP.Net

In this article I will explain how to display byte array i.e. Binary Data as Image on the web page in ASP.Net Image Control without using Generic handler and also without saving the file on disk.

HTML Markup

<form id="form1" runat="server">
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:Button ID="btnUpload" runat="server" Text="Upload"
    onclick="btnUpload_Click" />
<hr />
<asp:Image ID="Image1" Visible = "false" runat="server" Height = "100" Width = "100" />
</form>


Above you will see a FileUpload control to upload the Image File, a Button control to trigger the File upload process and an Image control to display the uploaded image file.
 
Displaying the Byte Array as Image
Below is the code that is being executed when the Upload button is clicked.
C#
 
protected void btnUpload_Click(object sender, EventArgs e)
{
    System.IO.Stream fs = FileUpload1.PostedFile.InputStream;
    System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
    Byte[] bytes = br.ReadBytes((Int32)fs.Length);
    string base64String = Convert.ToBase64String(bytes, 0, bytes.Length);
    Image1.ImageUrl = "data:image/png;base64," + base64String;
    Image1.Visible = true;
}