Create an IE Favorite to quickly resize your browser

Often times when editing or designing a web page or a site I use my full screen to take advantage of all the real estate my screen has to offer.  I also often times need to quickly see what a page will look like in a smaller screen resolution such as 1024×768.  Here is a quick tip to quickly and easily resize your IE browser to a specific size.
  1. Create a shortcut in your IE Favorites or in you Links folder.
  2. Rename this shortcut/favorite to “Resize Window to 1024 x 768″.
  3. Edit the properties of the shortcut and place the following line of javascript in the URL property.

    javascript:window.resizeTo(1024,768)

  4. Note: You may receive a warning prompt. Simply proceed.
  5. Save the properties and then click your new favorite “Resize Window to 1024×768″.

Your current window should now automatically resize to 1024 x 768.  I have a shortcut/favorite for both 800 x 600, 1024 x 768, and 1152 x 864 so I can quickly and easily resize my browser to a specific resolution.

Other common lower resolution sizes are:

javascript:window.resizeTo(800,600)
javascript:window.resizeTo(1024,768)
javascript:window.resizeTo(1280,720)
javascript:window.resizeTo(1280,800)

Important: When using IE 8 or later (using tabs), this will only work when you have only one tab in your IE browser. This will not work when you have multiple tabs open in the same IE window.
Advertisements

Trace.axd – Application Trace

The more you learn, the less you know.

Trying to keep up with the extensive areas of .NET and Microsoft products can easily bring you to this conclusion.  Its easy for us to continually focus on all the new technologies and versions (Whidbey and the .NET Framework 2.0) only to overlook some of the low hanging fruit – at least for me it is.  Remember, this is the “Simple Thoughts from a Simple Mind“ blog. ;)

One area I forgot about is the ASP.NET Trace – Trace.axd page.  As you may know, ASP.NET allows you to trace the processing for a single page or for all pages.  The trace output can be rendered at the end of each page.  Don’t forget (as I did) there is also the Trace.axd page that provides a nice list of traced pages such as this.

TracePic1 

The web.config file needs only a small change to make this available.

 TracePic2

Clicking on the View Details link for a page process will present you with the familiar trace detail.

Book: JavaScript, The Definitive Guide

JavaScript, The Definitive Guide

Book-JavaScript I have been reading the book JavaScript, The Definitive Guide by David Flanagan.  With the increasing amount of valuable and clear content available on Internet, I have found myself buying fewer books over the last three years or so.  I often find most books are only sprinkled with any real information and bloated will filler content just to sell the book.  This is certainly not the case for this JavaScript book.  Rarely can I sit down and read a technical book from cover to cover, but this book is certainly an exception, and exceptional!  I highly recommend it.  Every page has been worth my time.

Building a Better Busy Box – Ver 1.2

Building a Better Busy Box – Ver 1.2 (Processing… Please Wait)
 
Mark Wagner
Castle Rock Software, LLC

Updates

  • February 16, 2005 – Rewrite to use an IFRAME instead of a DIV tag.
  • January 7, 2005 – Fixed z-Index attribute.
  • November 13, 2004 – Original article

Summary: We often need to provide a user message informing the user that their request is “processing”.  Like the hour-glass mouse pointer lets the Windows user know the system is busy processing their last request, I have a simple, clean, and effect solution to providing this on web pages.

BusyBox Demo

Download Files

Technologies employed

  • JavaScript
  • HTML (ASP.NET)

Supported browsers 

  • Internet Explorer 6
  • Netscape Navigator 7.1, 7.2
  • Firefox 1.0
  • No other browsers have been tested

Introduction
Anyone who has used the Internet for more than a few hours has encountered times when the “Internet” is being slow.  I use the term “Internet” in jest here since it is often the term used when websites are not responding as quickly as we would like.  As most of us know, the problem is more often caused by an over-worked website, one that is unable to handle its current workload.  This article does not address any performance issues as that is a much larger topic for another time.  However, for those well designed and well cared-for websites there are very acceptable times when displaying a “processing” message to the user is very helpful and very appropriate.

I have certainly experienced times; as I am sure you have, where after clicking a submit or search button I began to wonder if the web server was going to process my request successfully.  Why shouldn’t it.  I didn’t expect it to take more than a second or two.  Performing functions like a search, report generation, or the processing of a large order, can often take more time than we would like.  These predictably slow responding places in an application are ideal candidates for user feedback in the form of a processing message.  As long as your website is not normally slow, your users will appreciate being notified of potentially long running processes.

There are a number of different approaches to accomplishing this.  One of the more common methods is to navigate to an intermediate page where an animated image and/or message are presented to the user.  The intermediate page then immediately initiates the process of navigating to the long-processing page.  This allows the intermediate “please wait” page to be displayed to the user while the long-processing target page is crunching away.  When the target page completes its long process it then begins rendering to the user’s browser, thus replacing the “please wait” message.  While this technique works well when navigating from page A to page B, it does not work well when a post-back (from page A to page A) is needed.  Additionally, having the benefits of things like ViewState become discarded.

My Approach
The approach I am about to cover functions just as well during a post-back as it does when navigating from page X to page Y.  Moreover, there is no need (or desire) to have an intermediate processing page.  If you are using a custom base page for your application; (i.e. a MasterPage), it becomes even easier to user.  I have added this to my personal CastlePage class making it very easy to use at anytime.

My approach is to pre-load my busy box message in a hidden IFRAME  tag on any page that will navigate (or post-back) to a potentially long running process. After all, my busy box message has a pretty small code footprint. The page will begin it’s unload process whenever the browser posts to a new page or performs a post-back. By placing JavaScript code in the onbeforeunload event of the body tag I can instantly reveal the busy box message to the user. Since this is part of the original page it will display immediately and remain visible until the new page completes its processing and begins to render in the user’s browser. Best of all, this works great with post-backs too.

My approach is:

  • Render the busy box message in a hidden IFRAME tag wherever we have a page that may post to a long processing page.
  • Display the busy box message before leaving this page (or posting back to the same page) by using the onbeforeunload event on the html body tag.  Note: An alternative method for browsers that do not support the onbeforeunload event is also discussed later.
  • Use JavaScript to perform a simple animation to the client.

Continuing to Learn
My first pass at this was to use an animated GIF image to fulfill my animated desires.  Putting together a quick prototype didn’t take long, but I immediately realized, remembered, discovered (pick one that best flatters me) that the .gif images stop animating once a post-back or navigation to another page is initiated.  This is consistent for all my test browsers (IE, NS, Firefox).  Although this realization didn’t bring my approach to a crashing halt, the thought of having only a static image was less than exciting.  Fortunately, I noticed that my image buttons still alternated to the hover image when I moved the mouse over them.  That’s when I realized that although GIF image may stop animating; JavaScript is still working hard – in all my test browsers.  With this said, I decided to animate the images using JavaScript.  This added a little more work, but as you will see, not much more work.

JavaScript Animation
First and foremost, I used my new copy of JavaScript – The Definitive Guide by David Flanagan as my sole JavaScript resource.  This now famous “Rhino” book continues to be well received by developers.  I have to agree as I found this book to be very well written and packed with excellent information.

An animated .GIF image is nothing more than a series of images that are displayed in rapid succession.  Since the web browsers won’t do this for me, I will do it myself using JavaScript.

My animation will require a number of images that will be displayed in rapid succession.  To allow the animated image to be developer-defined (customizable), I will need to know the number of images and the image names.  To help manage this animation and to keep it clean, the image names must have a predicable sequence number in a predictable position.  To accomplish this I have two image name requirements.

  • The names may be anything the developer wants as long as the image name prefix and suffix are consistent for every image.
  • The first image sequence number will be zero.

Here is the required image name format:

  • PrefixName + SequenceNumber + SuffixName

Here are valid image name examples:

  • BusyImage0.gif,  BusyImage1.gif,  BusyImage2.gif,  BusyImage3.gif, …, BusyImage6.gif
  • Images/BusyImage0.gif,  Images/BusyImage1.gif,  Images/BusyImage2.gif
  • Animate0Image.gif,  Animate1Image.gif,  Animate2Image.gif, …, Animate8Image.gif

The three image name properties used to define the images are ImageNamePrefix, ImageNameSuffix, and ImageCount; each of which are described below.

Before I dive into the details of my JavaScript, I thought it would be helpful to provide a quick overview of what my JavaScript BusyBox object interface will look like.  Here is a quick summary of the interface.

Constructor

BusyBox(id, varName, imageCount, imageNamePrefix, imageNameSuffix, imageDelay, width, height, url)

The parameters provided in this constructor are described in the properties section.

Properties

id

  • Defines the id of the IFrame tag to use with this instance of the BusyBox object.

VarName

  • This string value defines the name of the JavaScript variable containing the instance of this BusyBox object on the client’s machine.  This is needed so that we can use the setTimeout() statement, discussed later.

ImageCount

  • This integer value defines the number of images to use in the animation.

ImageNamePrefix

  • This string value defines the name prefix of the images that are used in the animation.
  • Example: “myBusyBoxImage_” or “images/myBusyBoxImage_”.

ImageNameSuffix

  • This string value defines the extension of the images that are used in the animation.
  • Example: “.gif” or “.jpg” or “_ani.gif”.

ImageDelay

  • This integer value defines the length of time in milliseconds to display each image.

Width

  • This defines the width (in pixels) of the busy box IFRAME tag.
  • Netscape and Firefix require this value to be defined.  For Internet Explorer users, the width is automatically calculated using the BusyBoxDiv tag attributes.

Height

  • This defines the height (in pixels) of the busy box IFRAME tag.
  • Netscape and Firefix require this value to be defined.  For Internet Explorer users, the width is automatically calculated using the BusyBoxDiv tag attributes.

BusyBoxUrl

  • Optional
  • Defines the url to the page containing the custom busy box layout.
  • If this value is omitted or null during the instantiation call, the internally defined layout is used.  The RenderContent() method is used to render the internal default layout.

Images

  • This array contains a reference to every image in the animation.  This property is populated during the constructor via the CacheImages() method.
  • This property should be treated as read-only.

CurrentImageIndex

  • This value is automatically calculated and incremented during the animation process.
  • This value should be treated as read-only.

Enabled

  • Get or set this Boolean value to enable or disable (a false value) the BusyBox using JavaScript.
  • This allows client-side JavaScript to conditionally enable or disable the BusyBox, should that become necessary.  A false value will prevent the busy box from being displayed when the Show method is called.
  • The default value is true.

IsAnimating

  • Returns a boolean value representing the state of the animation.
  • This should be treated as read-only.

IsVisible

  • Returns a boolean value representing the visibility state for the busy box.
  • This should be treated as read-only.

Methods

Show()

  • Displays the busy box by changing its visibility from hidden to visible.
  • Centers the busy box over the current window scroll position.
  • The BusyBox message will be displayed only if the Enabled property is true.  If the Enabled property is false, this Show method will do nothing.

Hide()

  • Hides the busy box by changing its visibility to hidden.
  • Provides a method to hide the BusyBox using JavaScript should it be necessary.  This may be called anytime using client-side JavaScript.
  • Note: This was fixed from the previous version.

Animate()

  • Performs the animation process.
  • This method should be treated as private.  There is no need to call this method directly.  The StartAnimate method should be called to start the animation process.

StartAnimation()

  • Starts the animation process.
  • Provides a method to start the animation process using JavaScript should it be necessary.  This may be called anytime using client-side JavaScript.

StopAnimate()

  • Stops the animation process.
  • Provides a method to stop the animation using JavaScript should it be necessary.  This may be called anytime using client-side JavaScript.

CacheImages()

  • Pre-loads the images from the server to improve the animation performance.  There is no need to directly call this method since it is called by the constructor.
  • This should be treated as private.  There should be no need to call this method.

GetIFrameDocument()

  • Returns a reference to the document object in the IFrame using the appropriate method depending on the browser version.
  • This should be treated as private.  There should be no need to call this method.

LoadUrl()

  • Changing the src attribute for an IFrame tag causes each new page to be added to the browsers history object. This causes undesired results for the user when they click the back button. Instead, we can use the document.location.replace() method to correctly load our busy box page into our IFrame.
  • Arguments: url – url to the busy box page. BusyBox.prototype.LoadUrl = function(url)
  • This should be treated as private.  There should be no need to call this method.

RenderContent()

  • This method is used when the default busy box layout is used; not a custom layout. This method is called when the url argument for the constructor is null.
  • This should be treated as private.  There should be no need to call this method.

Resize()

  • Resizes the busy box IFrame by setting its width and height attributes to the size of its contents for Internet Explorer browers.  For Netscape and Firefox, the width and height defined in the constructor are used to resize the IFrame.
  • This should be treated as private.  There should be no need to call this method.
  • Help: If anyone knows how to reliably determine ths size of the contents for Netscape and Firefox, please let me know.  Thanks.

Center()

  • Centers the busy box IFrame on the page regardless of the browsers scroll position. This ensures the busy box is presented to the user in a visible location in the window.
  • This should be treated as private.  There should be no need to call this method.

JavaScript Code

The JavaScript needed to perform the animation is pretty simple. The JavaScript found in the BusyBox.js file is static and used as is by placing a reference to it via the standard script tag. There is only one line of custom JavaScript code needed for any page, and that is to create an instance of the BusyBox object. Here is a sample of that code where I have chosen to use the variable name of “busyBox”.

var busyBox = new BusyBox(“BusyBoxIFrame”, “busyBox”, 4, “images/gears_ani_”, “.gif”, 125, 147, 206)

You will find the above line of code shown again in the HTML code below. I will not cover each line of JavaScript code; however, there are a couple key items worth pointing out. The first is the BusyBox constructor. The constructor executes the CacheImages method so that all the images used in the animation will be “pre-loaded” and ready for immediate use. The process used to cache the images simply forces the browser to retrieve the images during the initial page load. The images are not actually stored in the Images array. Additionally, the Images array provides an easy reference to each image used in the animation.

The Animate method sets the current image to display and then calls the JavaScript function setTimeout(). The set setTimeout() function executes the next statement in x number of milliseconds. As you can see, setTimeout() continues to call itself to display the next sequential image until the page is unloaded or until the animation is stopped using the StopAnimate() method. This is 100% of the animation process. Again, pretty simple (and straight out of the Rhino book).

The Show method has only a few small tasks, which are 1) to determine the size of the developer-defined busy box (for IE browsers).  2) Position the busy box in the center of the users browser regardless of the scroll position.  3) To begin the animation process.

The following code can be found in the CastleBusyBox.js file.  Note: The actual CastleBusyBox.js file contains a brief summary of comments for each method, and has a few more helper methods.

1function BusyBox(id, varName, imageCount, imageNamePrefix, imageNameSuffix, imageDelay, width, height, url) 2{
3   // Initialize object
4   this.id = id; 5   this.ImageCount = imageCount; 6   this.CurrentImageIndex = 0; 7   this.ImageWidth = 0; 8   this.ImageHeight = 0; 9   this.ImageNamePrefix = imageNamePrefix; 10   this.ImageNameSuffix = imageNameSuffix; 11   this.ImageDelay = imageDelay; 12   this.DivID = "BusyBoxDiv";
13   this.ImgID = "BusyBoxImg";
14   this.Enabled = true;
15   this.Width = width;
16   this.Height = height;
17
18   // Retain the name of the instantiated object variable so that we can animate 
19   // using the setTimeout statement
20   this.VarName = varName; 21
22   // Allows us to stop the animation with clearTimeout(), should we ever want to
23   this.timeout_id = null;
24
25   // Cache (pre-load) images
26   this.CacheImages(); 27
28   // Url to the page containing the busy box.
29   this.BusyBoxUrl = url; 30
31   // Get reference to the IFrame object
32   this.IFrame = document.getElementById(this.id);
33
34   // Hide the busy box
35   this.Hide();
36
37   if( this.BusyBoxUrl ) 38      // Load the busy box contents using a custom layout page.
39      this.LoadUrl(this.BusyBoxUrl); 40   else
41      // Load the busy box contents using the internally defined layout.
42      this.RenderContent(); 43
44   // If this browser does not support IFRAME tags then disable this control. The
45   // next version will implement the use of a DIV instead of the IFRAME tag; 
46   // even though there are a couple minor issues with using DIV tags.
47   if( !frames[this.id] )
48      this.Enabled = false;
49}
50
51BusyBox.prototype.GetIFrameDocument = function() 52{
53  var doc; 54
55   if( this.IFrame.contentDocument ) 56      // For NS6
57  doc = this.IFrame.contentDocument;
58   else if( this.IFrame.contentWindow )
59      // For IE5.5 and IE6
60      doc = this.IFrame.contentWindow.document;
61   else if( this.IFrame.document )
62      // For IE5
63      doc = this.IFrame.document;
64   else
65// TODO: Confirm this should be the default
66      doc = this.IFrame.document;
67
68   return doc;
69}
70
71BusyBox.prototype.LoadUrl = function(url) 72{
73   // Get a reference to the document object in the IFrame
74  var IFrameDoc = this.GetIFrameDocument(); 75
76   // Load the url using the replace method. This will prevent the browsers 
77   // history object from being updated with the new busybox url; thus allowing 
78   // the back button to function as desired for the user.
79  IFrameDoc.location.replace(url); 80}
81
82BusyBox.prototype.RenderContent = function()
83{
84   // Get the IFrame document object
85   var doc = this.GetIFrameDocument();
86
87   var wh = "width:" + this.Width + "; height:" + this.Height;
88   var style = " style='BORDER: navy 3px solid; POSITION: absolute; " + wh + "'";
89
90   doc.open();
91   doc.writeln("0px; Background-Color: white" _mce_style="margin: 0px; background-color: white;">");
92   doc.writeln("   <div id='" + this.DivID + "' align=center " + style + ">");
93   doc.writeln(" <img id='" + this.ImgID + "' src=''>");
94   doc.writeln("      <br><h3>Processing</h3>");
95   doc.writeln("   </div>");
96   doc.writeln("</body>");
97   doc.close();
98}
99
100BusyBox.prototype.Resize = function()
101{
102   // Resize the busy box IFrame.
103   if( BusyBox.IsBrowserIE() )
104   {
105      // Set the width by looking at its contents
106      var div = frames[this.id].document.getElementById(this.DivID); 107      this.IFrame.style.width = div.offsetWidth;
108      this.IFrame.style.height = div.offsetHeight;
109   }
110   else
111   {
112      // Set the width to the value specified.
113      this.IFrame.style.width = this.Width;
114      this.IFrame.style.height = this.Height;
115   }
116}
117
118BusyBox.prototype.Center = function()
119{
120   if( !this.IFrame )
121      return;
122
123   // Center the BusyBox in the window regardless of the scroll positions
124  var objLeft = (document.body.clientWidth - this.IFrame.offsetWidth) / 2;
125  var objTop = (document.body.clientHeight - this.IFrame.offsetHeight) / 2;
126  objLeft = objLeft + document.body.scrollLeft; 127  objTop = objTop + document.body.scrollTop; 128
129   // Position object
130   this.IFrame.style.position = "absolute";
131   this.IFrame.style.top = objTop;
132   this.IFrame.style.left = objLeft;
133}
134
135BusyBox.prototype.CacheImages = function()
136{
137   // Instantiate the array to store the image references
138   this.Images = new Array(this.ImageCount); 139
140   // Load all the images to cache into the aniframes array
141   for(var i = 0; i < this.ImageCount; i++) 142   {
143      this.Images[i] = new Image();
144      this.Images[i].src = this.ImageNamePrefix + i + this.ImageNameSuffix; 145   }
146}
147
148BusyBox.prototype.IsAnimating = function() 149{
150   if( this.timeout_id == null)
151      return false;
152   else
153      return true;
154}
155
156BusyBox.prototype.IsVisible = function() 157{
158  var ifrm = document.getElementById(this.id);
159
160   if( ifrm.style.visibility == "visible" && ifrm.style.width > 0 )
161      return true;
162   else
163      return false;
164}
165
166BusyBox.prototype.Animate = function()
167{
168   // Assign the current image sequence to display
169   if( frames[this.id] )
170      // browser supports frames
171      frames[this.id].document.getElementById(this.ImgID).src = this.Images[this.CurrentImageIndex].src; 172   else
173      // browser does not support frames
174      document.getElementById(this.ImgID).src = this.Images[this.CurrentImageIndex].src; 175
176   // Auto re-center and re-size the busy box.  This will force the busy box to 
177   // always appear in the center of the window even if the user scrolls.
178   this.Resize();
179   this.Center();
180
181   // Increment the current image index
182   this.CurrentImageIndex = (this.CurrentImageIndex + 1)%this.ImageCount; 183
184   // Display the next image in (imageDelay value) milliseconds (i.e. 125)
185   this.timeout_id = setTimeout(this.VarName + ".Animate();", this.ImageDelay); 186}
187
188BusyBox.prototype.StartAnimate = function() 189{
190   if( this.IsAnimating() ) 191      return;
192
193   this.Animate();
194}
195
196BusyBox.prototype.StopAnimate = function() 197{
198  clearTimeout(this.timeout_id);
199   this.timeout_id = null;
200}
201
202BusyBox.prototype.Hide = function()
203{
204   this.StopAnimate();
205
206   // Hide the busy box.
207   this.IFrame.style.visibility = "hidden";
208   this.IFrame.style.width = 0;
209   this.IFrame.style.height = 0;
210}
211
212BusyBox.prototype.Show = function()
213{
214   if( !this.Enabled )
215      return;
216
217   if( this.IsAnimating() || this.IsVisible() )
218      return;
219
220   this.Resize();
221   this.Center();
222
223   // Set the busy box to be visible and make sure it is on top of all other controls. 
224   this.IFrame.style.visibility = "visible";
225   this.IFrame.style.zIndex = "999999";
226
227   // Start the animation
228   this.StartAnimate();
229
 

The .ASPX (HTML) Code

The required code in the .aspx or html page is quite small and consists of four pieces of code.

The first html piece is the onbeforeunload event on the body tag.  This event is fired just before a page is unloaded.  This includes post-back and hyperlinks to other pages.  In the onbeforeunload event we place the JavaScript to display the Busy Box to the user prior to any action that results in leaving this page or reloading it.

Discuss how to use a SPAN tag around buttons or links instead of the onbeforeunload event of the body tag.

The second html piece is simply the reference to the JavaScript class defining the BusyBox class, which is used to display and animate the busy box.

The third html piece instantiates my BusyBox object and assigns it to my working variable named busyBox.  My sample uses four images and each image is displayed for 125 milliseconds with a width of 147 and height of 206.

Example:

var busyBox = new BusyBox(“BusyBoxIFrame”, “busyBox”, 4, “images/gears_ani_”, “.gif”, 125, 147, 206)

The fourth html piece is my Busy Box iframe tag.  The iframe is used to contain the BusyBox layout.  The BusyBox layout is nothing more than a div tag containing an img tag.  The size, color, and content of this busy box are completely up to you.  This allows you to create a busy box that is as generic or personalized as your site needs.  There are two important components in a busy box, the  div tag and the embedded img tag.  These two tags must contain the same id’s defined in the BusyBox JavaScript object properties DivID and ImgID.  The default values for these two properties are “BusyBoxDiv” for DivID, and “BusyBoxImg” for the ImgID property.  Assigning your html  div and img tags with these id values is the easiest.  However, you may assign any id you wish; however, you will need to assign your custom values to the busybox.DivID and busybox.ImgID properties immediately after the instantiation of your busybox JavaScript object.

Sample .ASPX (HTML)

<body onbeforeunload="busyBox.Show();">
   <script language="javascript" type="text/javascript" src="CastleBusyBox.js"></script>       <form>
         <P>    [Your Page Specific Content Here]    <iframe id="BusyBox1" name="BusyBox1" frameBorder="0" scrolling="no"ondrop="return false;"></iframe></P>
         <P>
	<INPUT id="Submit1" type="submit" value="Submit" name="Submit1"></P>
      <script language="javascript" type="text/javascript">          // Instantiate BusyBox object          var busyBox =    new BusyBox("BusyBox1", "busyBox", 4, "images/gears_ani_", ".gif", 125, 147, 207);       </script>
   </form>
</body>
 

Alternatives to Using the OnBeforeUnload Event

The onbeforeunload is supported by Internet Explorer 6, Netscape 7.2 (not 7.1), and Firefox 1.0.  The onbeforeunload event may not be the best solution for your particular needs.  Another solution is to place the busybox.Show() method in the onclick event of the html elements (button, link etc.) that need to cause the busy box to appear.  If the particular html tag does not have an onclick event, you can wrap your control in a span tag and use the onclick event of the span tag.  I use this all the time.

Example:

<span onclick="busyBox.Show();">
	<a href="anypage.htm">Any Page</a>
</span>

This allows you to specifically control which buttons and/or links cause the busy box to appear.

Another issue surfaced by users of the pervious version was the busy box appearing and remaining on the screen when a popup window was launched.  This assumes your are using the onbeforeunload event, and you want to prevent the busy box from appearing.  You can prevent this from happening by placing a “return false;” after the popup statement in your javascript event code.

Example:

<A onclick="window.open('anypage.htm'); return false;" href="#"> Open window</A>

Creating a BusyBox Web Control

I have created an ASP.NET web control to allow for easy use in ASP.NET pages.  You can find the control in my BusyBox Web Control article – to be posted shortly with a link insterted here.

Page Events: Order and PostBack (by Paul Wilson)

This is a “must have” article by Paul Wilson.  I have copied it to my site for easy reference for myself.
Paul Wilson
www.WilsonDotNet.com
www.ASPAlliance.com/PaulWilson
 

Initialization

The first method that executes when a page is requested is always the constructor. You can initialize many of the custom properties or objects in the page at this time, although there are a few limitations since the page hasn’t fully initialized yet. In particular, you will have to use the HttpContext.Current object to access the Request QueryString, Form, and Cookies collections, along with the Cache object. However, there is no way to access the Session collection within the constructor.

The next method that executes is the AddParsedSubObject method, which actually adds all the individual controls that make up a page into the control collection tree. This method is typically overridden by some of the advanced page template solutions in order to add the page contents into a particular control in the page template. This method is recursively called on all children controls for each page control, and each of these controls is initialized at this time, starting with the innermost.

The next method that executes is the DeterminePostBackMode method of the page class. This method allows you to affect the value of IsPostBack and all the related events, which might be useful if you need to load ViewState from a database for a redirect, since we will see that ViewState is only restored when IsPostBack is actually true. Just return null to force non-PostBack and return Request.Form to force a PostBack. This is not recommended, except in special cases, since it affects other events too.

The page’s OnInit method is executed next, which is typically the first method used. By the time this occurs, all the controls defined in your page will be initialized, which means that all the original values specified in the aspx page will be applied. However, ViewState and any posted values will not have been applied to controls yet, so anything that changed as a result of the code or user will not yet be restored. This is usually the best place to create, and recreate, any dynamic controls used.

Restore and Load

The next method, LoadPageStateFromPersistenceMedium, only executes for PostBacks. This method is overridden when you have altered how the page’s ViewState was saved, later in the SavePageStateToPersistenceMedium, when using Session or Custom Stores. The default implementation assumes ViewState is a Base64 encoded hidden form field, but this can be changed in these two methods using code found in this related article. Note that this method does not actually restore ViewState to the page or its controls.

After ViewState is retrieved, the next method, LoadViewState, restores it to the page, and then recursively to each control and their children, but again only on PostBacks. After this executes, each control will now be restored to the state it was last time, but user posted values will still not be applied, since this is not part of ViewState. The best use of this method is to restore any dynamic controls you created in events, based on values you must manually save in ViewState, which is now available to use.

The next method, ProcessPostData, only executes for PostBacks, and it is not able to be overridden, since it is a private method implemented by the base page class. This method finally restores the user’s posted form values by matching up controls with the names of the values, which means your page will finally be fully restored. The only catch is that dynamic controls must be created prior to this page method. This is also the method that records changes in values for the changed events later.

The page’s OnLoad method is executed next, which is typically used for most code, since this is the first place in the page lifecycle that all values are restored. Most code checks the value of IsPostBack to avoid unnecessarily resetting state. You may also wish to call Validate and check the value of IsValid in this method. You can also create dynamic controls in this method, and all the control’s methods will be executed to catch up, including ViewState, but posted values would not be.

Raised Events

The next method, ProcessPostData, is actually a second pass of the earlier method, which still only executes for PostBacks and is not overridable since private method. This second pass always seems a little odd when you first notice it in the page trace, but it occurs because dynamic controls recreated in OnLoad need their posted values. Any controls that are dynamically created after this method, while having ViewState restored, will not get their posted values nor be able to trigger any changed events.

The next method, RaiseChangedEvents, also occurs only for PostBacks, and it too is a private method that is implemented in the base page class that cannot be overridden. This is the time in the page lifecycle that the changed events are actually raised, based on the differences that ProcessPostData noted before and after posted values. You may also want to call Validate and check the value of IsValid, if not already. There is no guarantee about the order that multiple changed events will be raised.

The next method, RaisePostBackEvent, also occurs only for PostBacks, and it too is a private method that is implemented in the base page class that cannot be overridden. This is where the event that actually submitted the form, unless using AutoPostBack, is actually raised, typically a button, or a control that uses javascript to submit. If not manually called already, Validate is also called, when using some Validators. Note a bug in IE sometimes allows the Enter key to submit without triggering an event.

The page’s OnPreRender method is executed next, which is typically the last chance to affect the page and its controls before it is rendered to the client’s browser. You can also create dynamic controls in this method, and all the control’s methods will be executed to catch up, including ViewState, but the earlier private methods will not receive another pass, meaning no posted values are restored and no events. This is a good place to catch a PostBack without an event due to the bug noted in IE.

Save and Render

The next method that executes, regardless whether PostBack or not, is SaveViewState which recursively runs for each control and their children, to create the ViewState. ViewState basically stores any property values that are different from the original values that are defined in the aspx page, whether changed in the code or by the user. Note that control values are saved according to their location in the control tree, so ViewState can get corrupted if dynamic controls are later added in wrong positions.

The next method, SavePageStateToPersistenceMedium, actually saves the page ViewState. This method is overridden, along with LoadPageStateFromPersistenceMedium, to save the ViewState either to Session or a Custom Store, instead of using the hidden field. This is useful for low bandwidth cases, and Session is the default for Mobile Pages. See the code found in this related article for details of using these two methods, and note that a bug in ASP.NET requires a __VIEWSTATE field to be sent, even if empty.

The page’s Render method is executed next, which recursively runs for each control and their children, to actually create and send the resulting html to the browser. This method is used in some page template solutions to add common headers and footers to the page without using server controls, which always have a little extra overhead. Note that changes made here must be pure html, since controls are done at this time. You can capture the html output using StringBuilder, StringWriter, and HtmlTextWriter.

The very last method to be executed is OnUnload, which also calls the Dispose method. This method gives you a chance to cleanup any unmanaged resources used in the page, typically things like closing any open files or database connections open earlier. Note that this method runs only after the page has been sent to the client’s browser, so it will only affect server objects, and it will not show up in a trace of the page. And that’s the page lifecycle — everything runs all over again with each new request.

Listing 1: Page Events Summary


Method PostBack Controls

Constructor Always All
AddParsedSubObject Always All
DeterminePostBackMode Always Page
OnInit Always All

LoadPageStateFromPersistenceMedium PostBack Page
LoadViewState PostBack All
ProcessPostData1 PostBack Page
OnLoad Always All

ProcessPostData2 PostBack Page
RaiseChangedEvents PostBack Page
RaisePostBackEvent PostBack Page
OnPreRender Always All

SaveViewState Always All
SavePageStateToPersistenceMedium Always Page
Render Always All
OnUnload Always All

Author Bio

Paul Wilson is a software architect in Atlanta, currently with a medical device company. He specializes in Microsoft technologies, including .NET, C#, ASP, SQL, COM+, and VB. His WilsonWebForm Control allows Multiple Forms and Non-PostBack Forms in ASP.NET. He is a Microsoft MVP in ASP.NET and is also recognized as an ASPFriend’s ASPAce/ASPElite. He is a moderator on Microsoft’s ASP.NET Forums, as well as one of the top posters. He is certified in .NET (MCAD), as well as also holding the MCSD, MCDBA, and MCSE. Please visit his website, www.WilsonDotNet.com, or email him at Paul@WilsonDotNet.com.

GetPageHTML – Get the HTML code for a given URL

GetPageHTML – C# code sample to get the HTML code for a given page URL

public class SampleCode 
{ 
    public SampleCode() 
    { }

    // Download the HTML source code at the specified URL
    // You can optionally specify the username/password credentials, 
    // in case the page uses Basic Authentication 
    // Returns a null string if any error occurs 
    public static string GetHtmlPageSource(string url) 
    { 
        return GetHtmlPageSource(url, null, null); 
    }

    public static string GetHtmlPageSource(string url, string username, string password)
    { 
        System.IO.Stream st = null; 
        System.IO.StreamReader sr = null;

        try
        { 
            // make a Web request 
            System.Net.WebRequest req = System.Net.WebRequest.Create(url);

            // if the username/password are specified, use these credentials 
            if (username != null && password != null) 
                req.Credentials = new System.Net.NetworkCredential(username, password);

            // get the response and read from the result stream 
            System.Net.WebResponse resp = req.GetResponse(); 
            st = resp.GetResponseStream(); 
            sr = new System.IO.StreamReader(st);

            // read all the text in it 
            return sr.ReadToEnd(); 
        } 
        catch (Exception ex) 
        { 
            return string.Empty; 
        } 
        finally 
        { 
            // always close readers and streams 
            sr.Close(); 
            st.Close(); 
        } 
    } 
}

Calling A Page Using ShowPage vs. Response.Redirect

Calling A Page Using ShowPage vs. Response.Redirect

Mark Wagner
May 21, 2004

Applies to

  • Response.Redirect
  • Calling a page
  • State Management

Summary

This article shows how you can call a page using strongly typed parameters just as you would call any common method.

Contents

  • Introduction
  • Response.Redirect
  • Creating Page Parameters
  • Using ShowPage and PageUrl

Introduction

The typical technique used to call a page is using the Response.Redirect method.  This often involves passing relative data in the form of a query string.  The query string is just as it implies, a string of data.  Additionally, the query string is a very unsecure method often requiring the query string to be encrypted.

Another technique is to provide a method on each page called ShowPage.  The ShowPage method provides a number of benefits.  This article will cover how simple you can accomplish this.

  • Strongly typed parameters.
  • Exposure of required parameters via the interface
  • Encapsulated parameter state management
  • Improved security (no query string visibility)
  • Page mobility within the web application

Response.Redirect

Below is an example of using the Response.Redirect method.  This looks very simple, and it is for the most part.

Example
string query = "?id=" + someVariable;
Response.Redirect("~/FolderX/PageX.aspx" + query);

Although this method works perfectly well, it can pose a security risk under certain circumstances.  As a rule, the query string should be used with the understanding that the data can be modified by the user.  The query string should always be considered as user input and therefore it should always be subject to the same validation requirements as user input is.  Page parameters address this.

The query string does not support strongly typed values.  Just to be fair, its a good thing the query string doesn’t require strongly typed values, and it is definitely worth having at times.  However, there are several times when the use of strongly typed variables is useful.  Using the query string also forces us to convert all values to a string before calling the page.  Additionally, we must to convert these string values obtained from the query string back to their native data types on the called page.  This requires the developer to research any required parameters, usually by opening the source code for that page and inspecting the page’s Page_Load method or page documentation.  Page parameters provide for strongly typed values as well as exposure via the page’s class interface.

The session object is another mechanism for managing state between page calls.  This also works well, but it requires the calling page to know the name of the session variable(s) to use in storing the value(s).  Page parameters resolve this using encapsulation.

With most web projects the pages are not moved around all that often once they are created.  However, there are times when they do need to be moved.  Page parameters addresses this by encapsulating the page url in a central location and removes the need to hard-code or duplicate this information in other pages.

Creating Page Parameters

Using page parameters involves creating one static property and one static method.  These new methods should be static for optimal performance and ease of use for the developer.  As we know, static methods are available as part of the class definition and do not require the page class to be instantiated.

PageUrl property

The first property we create is the PageUrl property.  This encapsulates the url used to call this page.  The string containing the url should be relative to the root of the application.  Using the HttpContext.Current.Request.ApplicationPath ensures we return the url relative to the web applications root folder.  Additionally, exposing this url as a public method allows the url to be available for use when needed in situations such as for a menu link, hyperlink, or any other url related need.  The following is an example of the PageUrl property to add to you page.

Example
public static string PageUrl
{
  get
  {
    return HttpContext.Current.Request.ApplicationPath + "/FolderX/PageX.aspx";
  }
}

ShowPage Method

The second method needed is the ShowPage method.  This facilitates the need to call (redirect to) this page.  When calling a page it is often necessary to pass data to that page.  This is often done using the query string, session state, or some other mechanism.  Again, although these methods work fine, there are several drawbacks to these methods as discussed above in the Response.Redirect section.

In the example below we allow the user to pass objects such as a dataset to the page.  The calling page does not need to be concerned with how the required page parameters are managed.

Example
public static void ShowPage(int selectedItemPK, DataSet largeDataSet)
{
 SessionState("PageX.SelectedPK") = selectedItemPK; 
 SessionState("PageX.DataSet") = largeDataSet;
 HttpContext.Current.Response.Redirect(PageX.PageUrl);
}

Additionally, you can overload the ShowPage method to expose the acceptable combination of parameters when calling this page.

Example
public static void ShowPage(DataSet largeDataSet)
{
 ShowPage(DataSet largeDataSet);
}

public static void ShowPage()
{
 ShowPage((DataSet) null);
}

Using ShowPage and PageUrl

Having implemented these two simple methods in our page we have reduced the development time for any developer needing to call our page.  The developer simply uses the page class name to access either the ShowPage mothod or the PageUrl property.  As you will see below, using these methods is very simple.

Using the PageUrl property

Obtaining the url used to call a page is easily retrieved at run-time via the PageUrl property.  Again, this is retrieved at run-time and not hard-coded as is usually done.  In this example we are assigning the page url to a menu object.

Example
menuItem.TargetUrl = PageX.PageUrl;

Using the ShowPage method

Using the ShowPage method becomes very easy for any developer needing to call your page.  The available and required parameters are easily visible to the developer at design time via Intellisense.  Additionally, the expected data type for each parameter is easily accessible and visible to the developer.

Example
PageX.ShowPage(newDataSet);

As you can see, providing a strongly typed interface to call your page is very simple and only requires a few lines of code.

ASP.NET Interview Questions

ASP.NET Interview Questions

This is a list of questions I have gathered and created over a period of time from my experience, many of which I felt where incomplete or simply wrong.  I have finally taken the time to go through each question and correct them to the best of my ability.  However, please feel free to post feedback to challenge, improve, or suggest new questions.  I want to thank those of you that have contributed quality questions and corrections thus far.

There are some questions in this list that I do not consider to be good questions for an interview.  However, they do exist on other lists available on the Internet so I felt compelled to keep them here for easy access.

  1. Describe the role of inetinfo.exe, aspnet_isapi.dll andaspnet_wp.exe in the page loading process.
    inetinfo.exe is theMicrosoft IIS server running, handling ASP.NET requests among other things.When an ASP.NET request is received (usually a file with .aspx extension), the ISAPI filter aspnet_isapi.dll takes care of it by passing the request tothe actual worker process aspnet_wp.exe.
     
  2. What’s the difference between Response.Write() andResponse.Output.Write()?
    Response.Output.Write() allows you to write formatted output. 
     
  3. What methods are fired during the page load?
    Init() – when the page is instantiated
    Load() – when the page is loaded into server memory
    PreRender() – the brief moment before the page is displayed to the user as HTML
    Unload() – when page finishes loading. 
     
  4. When during the page processing cycle is ViewState available?
    After the Init() and before the Page_Load(), or OnLoad() for a control. 
     
  5. What namespace does the Web page belong in the .NET Framework class hierarchy?
    System.Web.UI.Page 
     
  6. Where do you store the information about the user’s locale?
    System.Web.UI.Page.Culture 
     
  7. What’s the difference between Codebehind="MyCode.aspx.cs" andSrc="MyCode.aspx.cs"?
    CodeBehind is relevant to Visual Studio.NET only. 
     
  8. What’s a bubbled event?
    When you have a complex control, like DataGrid, writing an event processing routine for each object (cell, button, row, etc.) is quite tedious. The controls can bubble up their eventhandlers, allowing the main DataGrid event handler to take care of its constituents. 
     
  9. Suppose you want a certain ASP.NET function executed on MouseOver for a certain button.  Where do you add an event handler?
    Add an OnMouseOver attribute to the button.  Example: btnSubmit.Attributes.Add("onmouseover","someClientCodeHere();"); 
     
  10. What data types do the RangeValidator control support?
    Integer, String, and Date. 
     
  11. Explain the differences between Server-side and Client-side code?
    Server-side code executes on the server.  Client-side code executes in the client’s browser. 
     
  12. What type of code (server or client) is found in a Code-Behind class?
    The answer is server-side code since code-behind is executed on the server.  However, during the code-behind’s execution on the server, it can render client-side code such as JavaScript to be processed in the clients browser.  But just to be clear, code-behind executes on the server, thus making it server-side code. 
     
  13. Should user input data validation occur server-side or client-side?  Why?
    All user input data validation should occur on the server at a minimum.  Additionally, client-side validation can be performed where deemed appropriate and feasable to provide a richer, more responsive experience for the user. 
     
  14. What is the difference between Server.Transfer and Response.Redirect?  Why would I choose one over the other?
    Server.Transfer transfers page processing from one page directly to the next page without making a round-trip back to the client’s browser.  This provides a faster response with a little less overhead on the server.  Server.Transfer does not update the clients url history list or current url.  Response.Redirect is used to redirect the user’s browser to another page or site.  This performas a trip back to the client where the client’s browser is redirected to the new page.  The user’s browser history list is updated to reflect the new address. 
     
  15. Can you explain the difference between an ADO.NET Dataset and an ADO Recordset?
    Valid answers are:
    · 
    A DataSet can represent an entire relational database in memory, complete with tables, relations, and views.
    ·  A DataSet is designed to work without any continuing connection to the original data source.
    ·  Data in a DataSet is bulk-loaded, rather than being loaded on demand.
    ·  There’s no concept of cursor types in a DataSet.
    ·  DataSets have no current record pointer You can use For Each loops to move through the data.
    ·  You can store many edits in a DataSet, and write them to the original data source in a single operation.
    ·  Though the DataSet is universal, other objects in ADO.NET come in different versions for different data sources. 
     
  16. What is the Global.asax used for?
    The Global.asax (including the Global.asax.cs file) is used to implement application and session level events. 
     
  17. What are the Application_Start and Session_Start subroutines used for?
    This is where you can set the specific variables for the Application and Session objects. 
     
  18. Can you explain what inheritance is and an example of when you might use it?
    When you want to inherit (use the functionality of) another class.  Example: With a base class named Employee, a Manager class could be derived from the Employee base class. 
     
  19. Whats an assembly?
    Assemblies are the building blocks of the .NET framework. Overview of assemblies from MSDN 
     
  20. Describe the difference between inline and code behind.
    Inline code written along side the html in a page. Code-behind is code written in a separate file and referenced by the .aspx page. 
     
  21. Explain what a diffgram is, and a good use for one?
    The DiffGram is one of the two XML formats that you can use to render DataSet object contents to XML.  A good use is reading database data to an XML file to be sent to a Web Service. 
     
  22. Whats MSIL, and why should my developers need an appreciation of it if at all?
    MSIL is the Microsoft Intermediate Language. All .NET compatible languages will get converted to MSIL.  MSIL also allows the .NET Framework to JIT compile the assembly on the installed computer. 
     
  23. Which method do you invoke on the DataAdapter control to load your generated dataset with data?
    The Fill() method. 
     
  24. Can you edit data in the Repeater control?
    No, it just reads the information from its data source. 
     
  25. Which template must you provide, in order to display data in a Repeater control?
    ItemTemplate. 
     
  26. How can you provide an alternating color scheme in a Repeater control?
    Use the AlternatingItemTemplate. 
     
  27. What property must you set, and what method must you call in your code, in order to bind the data from a data source to the Repeater control?
    You must set the DataSource property and call the DataBind method. 
     
  28. What base class do all Web Forms inherit from?
    The Page class. 
     
  29. Name two properties common in every validation control?
    ControlToValidate property and Text property. 
     
  30. Which property on a Combo Box do you set with a column name, prior to setting the DataSource, to display data in the combo box?
    DataTextField property. 
     
  31. Which control would you use if you needed to make sure the values in two different controls matched?
    CompareValidator control. 
     
  32. How many classes can a single .NET DLL contain?
    It can contain many classes.
     

Web Service Questions

  1. What is the transport protocol you use to call a Web service?
    SOAP (Simple Object Access Protocol) is the preferred protocol. 
     
  2. True or False: A Web service can only be written in .NET?
    False 
     
  3. What does WSDL stand for?
    Web Services Description Language. 
     
  4. Where on the Internet would you look for Web services?
    http://www.uddi.org 
     
  5. True or False: To test a Web service you must create a Windows application or Web application to consume this service?
    False, the web service comes with a test page and it provides HTTP-GET method to test.
     

State Management Questions

  1. What is ViewState?
    ViewState allows the state of objects (serializable) to be stored in a hidden field on the page.  ViewState is transported to the client and back to the server, and is not stored on the server or any other external source.  ViewState is used the retain the state of server-side objects between postabacks. 
     
  2. What is the lifespan for items stored in ViewState?
    Item stored in ViewState exist for the life of the current page.  This includes postbacks (to the same page). 
     
  3. What does the "EnableViewState" property do?  Why would I want it on or off?
    It allows the page to save the users input on a form across postbacks.  It saves the server-side values for a given control into ViewState, which is stored as a hidden value on the page before sending the page to the clients browser.  When the page is posted back to the server the server control is recreated with the state stored in viewstate. 
     
  4. What are the different types of Session state management options available with ASP.NET?
    ASP.NET provides In-Process and Out-of-Process state management.  In-Process stores the session in memory on the web server.  This requires the a "sticky-server" (or no load-balancing) so that the user is always reconnected to the same web server.  Out-of-Process Session state management stores data in an external data source.  The external data source may be either a SQL Server or a State Server service.  Out-of-Process state management requires that all objects stored in session are serializable.