Web Q&A

Smart Navigation, ASP.NET Project Structure, and More

Edited by Nancy Michell

Q I'm getting intermittent errors in Microsoft Internet Explorer, and they seem to be related to using ASP.NET 2.0 with SmartNavigation turned on. What exactly does SmartNavigation do and when should I use it?

Q I'm getting intermittent errors in Microsoft Internet Explorer, and they seem to be related to using ASP.NET 2.0 with SmartNavigation turned on. What exactly does SmartNavigation do and when should I use it?

A SmartNavigation is a property of the Page class in System.Web.UI. When a request comes in to Internet Explorer 5.5 or higher and SmartNavigation is turned on (set to true), the following actions are performed:

  • The flash caused by navigation is eliminated
  • The scroll position is persisted when moving from page to page
  • Element focus is persisted between navigations
  • Only the last page state in the browser's history is retained

A SmartNavigation is a property of the Page class in System.Web.UI. When a request comes in to Internet Explorer 5.5 or higher and SmartNavigation is turned on (set to true), the following actions are performed:

  • The flash caused by navigation is eliminated
  • The scroll position is persisted when moving from page to page
  • Element focus is persisted between navigations
  • Only the last page state in the browser's history is retained

However, according to the Microsoft® .NET Framework Class Library documentation, smart navigation is best used only with ASP.NET pages that require frequent postbacks but have visual content that does not change dramatically on return.

In most circumstances, you should not set this property in code. Set the SmartNavigation attribute to true in the @ Page directive in the .aspx file. When the page is requested, the dynamically generated class sets this property for you. Smart navigation is a feature that you must test in your particular scenarios to be sure the proper behavior is exhibited.

Q I am experiencing some problems adopting ASP.NET 2.0, mainly because I need to compartmentalize functionality within a large Web application. There will be number of feature compartments under the root virtual directory, like so:

Internet Bank (virtual directory)
 Accounts (folders)
 ApplicationForms (folders)
 Investments (folders)

Q I am experiencing some problems adopting ASP.NET 2.0, mainly because I need to compartmentalize functionality within a large Web application. There will be number of feature compartments under the root virtual directory, like so:

Internet Bank (virtual directory)
 Accounts (folders)
 ApplicationForms (folders)
 Investments (folders)

The subdirectories cannot be virtual directories as all of the areas need to share session state which is scoped to virtual directories. With ASP.NET 2.0 all of these extraneous code files have to be placed in App_Code in order to be compiled, making it really hard to understand what files in App_Code are used by what functional areas. Can you suggest an easy solution to this?

A Your UI codebehind code lives with the .aspx or .ascx file—so it will live side-by-side with the actual content. It's typically recommended that you encapsulate all per-UI form code in these files (similar to how it's done today with Visual Studio® .NET 2003). App_Code is then used for shared code across the application.

A Your UI codebehind code lives with the .aspx or .ascx file—so it will live side-by-side with the actual content. It's typically recommended that you encapsulate all per-UI form code in these files (similar to how it's done today with Visual Studio® .NET 2003). App_Code is then used for shared code across the application.

You could organize the shared code using subfolders underneath the App_Code directory. Then use regular folders to cleanly organize your pages/user-controls across the project and keep all codebehind code with it (the default). See Figure 1 for an example.

Figure 1 Project Folders

App_Code
     \Accounts
        MyAccounts.cs
    \ApplicationForms
        MyApplicationForm.cs
    \Investments
        MyInvestment.cs
 
\Accounts
    MyAccountsPage.aspx
    MyAccountsPage.aspx.cs
 
\ApplicationForms
    MyApplicationFormPage.aspx
    MyApplicationFormPage.aspx.cs
 
    \Investments
        MyInvestmentPage.aspx
        MyInvestmentPage.aspx.cs

Otherwise, rather than use App_Code and have a single place where all shared code is stored, partition it into three separate class-library projects that the Web project links to. These would then be deployed as DLLs in the \bin directory.

Q I am building a Web service in C# that deals with a global Hashtable that is accessed by many users simultaneously. Is it safe to have multiple people reading the Hashtable without a lock while other threads are writing to it? Do I need a lock every time I read something from the Hashtable?

Q I am building a Web service in C# that deals with a global Hashtable that is accessed by many users simultaneously. Is it safe to have multiple people reading the Hashtable without a lock while other threads are writing to it? Do I need a lock every time I read something from the Hashtable?

A If a writer adds a value that causes the basic structure of the Hashtable to redistribute or that causes buckets to be added, you will run into trouble. You should use the ReaderWriterLock to achieve thread safety. Also note that if you intend to use IEnumerable to enumerate the items in the Hashtable, an exception will be thrown if the Hashtable changes between calls to MoveNext.

A If a writer adds a value that causes the basic structure of the Hashtable to redistribute or that causes buckets to be added, you will run into trouble. You should use the ReaderWriterLock to achieve thread safety. Also note that if you intend to use IEnumerable to enumerate the items in the Hashtable, an exception will be thrown if the Hashtable changes between calls to MoveNext.

For the .NET Framework 2.0, the docs for Hashtable say it's safe for multiple readers and a single writer. The page at Hashtable.Synchronized Method states that "A System.Collections.Hashtable can support one writer and multiple readers concurrently."

Q I have found that when catching the oncontextmenu event to create a pop-up window, the pop-up is being blocked by the Internet Explorer pop-up blocker in Windows XP SP2, but only in the Internet zone. It was my understanding that any user-initiated pop-up should not be blocked. Is this by design? Here's the code I'm using:

<html><body>
<a oncontextmenu="showModalDialog('about:blank');return false">
    <b>Right</b> click here to invoke a modal dialog.
</a>
<a oncontextmenu="window.open('about:blank');    return false">
    <b>Right</b> click here to invoke a window.open.
</a>
</body></html>

Q I have found that when catching the oncontextmenu event to create a pop-up window, the pop-up is being blocked by the Internet Explorer pop-up blocker in Windows XP SP2, but only in the Internet zone. It was my understanding that any user-initiated pop-up should not be blocked. Is this by design? Here's the code I'm using:

<html><body>
<a oncontextmenu="showModalDialog('about:blank');return false">
    <b>Right</b> click here to invoke a modal dialog.
</a>
<a oncontextmenu="window.open('about:blank');    return false">
    <b>Right</b> click here to invoke a window.open.
</a>
</body></html>

A WM_CONTEXTMENU is not considered to be a user-initiated action. You could display a floating div or use window.createPopup instead of HTML dialogs or window.open. The reason this only occurs in the Internet zone is that the pop-up blocker is only enabled by default in Internet and untrusted zones.

A WM_CONTEXTMENU is not considered to be a user-initiated action. You could display a floating div or use window.createPopup instead of HTML dialogs or window.open. The reason this only occurs in the Internet zone is that the pop-up blocker is only enabled by default in Internet and untrusted zones.

The rules concerning pop-ups say that they are not blocked if they are:

  • Opened by a link which the user clicked.
  • Opened by applications that are running on the computer. These applications can include adware.
  • Opened, on user-initiated actions, by ActiveX® controls that are instantiated from a Web site.
  • Opened from the Trusted Sites or Local Intranet zones.
  • Launched from a Web site on a user's allow list. (Users can add Web sites to their allow list through the pop-up blocker settings.)
  • Launched with the window.createPopup method. Note that window restrictions allow only one pop-up window at a time to be open on a page, and that they restrict pop-up windows launched with this method to the Internet Explorer client window.

Whether pop-up windows appear in each of these cases is ultimately determined by the user. Users can configure the pop-up blocker to be more or less restrictive, or they can choose to turn it off altogether.

For more information, see "About the Pop-up Blocker".

Q Is there a setting to disable the address bar in Internet Explorer via Group Policy? What other browser settings can I enforce through policy?

Q Is there a setting to disable the address bar in Internet Explorer via Group Policy? What other browser settings can I enforce through policy?

A Yes, you can disable the address bar and set lots of other restrictions using Group Policy. The browser restrictions that are available with Internet Explorer 6.0 SP1 are shown in Figure 2. The instructions for setting the browser restrictions can be found in the Knowledge Base article located at The restrictions that are available to Internet Explorer 6.0 SP1.

A Yes, you can disable the address bar and set lots of other restrictions using Group Policy. The browser restrictions that are available with Internet Explorer 6.0 SP1 are shown in Figure 2. The instructions for setting the browser restrictions can be found in the Knowledge Base article located at The restrictions that are available to Internet Explorer 6.0 SP1.

Figure 2 Browser Restrictions

Setting Description
NoFileOpen Turns off the Open command on the File menu.
NoFileNew Turns off the New command on the File menu.
NoBrowserOptions Turns off the Internet Options command on the Tools menu.
NoSelectDownloadDir Turns off Save on the File Download dialog box.
NoBrowserClose Turns off Close button, located in the upper-right corner of the window or dialog box. This registry value also turns off the Close command on the File menu.
NoBrowserSaveAs Removes the Save As command on the File menu.
NoFavorites Removes the Favorites menu and disables the Favorites bar.
NoHelpItemTipOfTheDay Removes the Tip of the Day command on the Help menu.
NoHelpItemNetscapeHelp Removes the For Netscape Users command on the Help menu.
NoHelpItemTutorial Removes the Internet Explorer Tutorial command on the Help menu.
NoHelpItemSendFeedback Removes the Send Feedback command on the Help menu.
NoPrinting Removes the Print command on the File menu.
No_LaunchMediaBar Removes the Media Bar command on the toolbar when the user plays online content.
NoTheaterMode Disables the F11 key (full-screen mode).
NoBrowserContextMenu Disables the right-click shortcut menu on a Web page.
NoFindFiles Turns off the F3 command and the Search bar.
NoViewSource Turns off the Source command on the View menu. However, to completely disable user's ability to view the source, the NoBrowserContextMenu value must be added.
NoOpeninNewWnd Turns off the CTRL+N command and the Open command to open a new window.
AlwaysPromptWhenDownload Makes the "Always ask before opening this type of file" checkbox on the Safe Open File dialog box unavailable so that it is always selected.
NoNavButtons Disables the Back and Forward navigation buttons on the toolbar.
NoHelpMenu Disables the Internet Explorer Help menu.
No_MediaBarOnlineContent Disallows the playing of online content.
NoToolbarOptions The user receives the error message when they try to click any command on the View menu except Customize and Lock the Toolbars.
NoToolBar Removes the toolbar. However you can add standard buttons on the View Toolbar menu. To completely enable this setting, you must enable the NoToolbarOptions DWORD value.
NoAddressBar Removes the Address bar.
NoLinksBar Removes the Link bar. The user receives an error message when they try to click Links on the Toolbar menu.

Q I'm using an application (developed in Visual Basic) in a Citrix environment. Each time you open a Web link, it is supposed to open in the same Internet Explorer window. This works fine in the old production environment, but in our new Citrix farm a new Internet Explorer window opens each time. How can I work around this without touching the Visual Basic application?

Q I'm using an application (developed in Visual Basic) in a Citrix environment. Each time you open a Web link, it is supposed to open in the same Internet Explorer window. This works fine in the old production environment, but in our new Citrix farm a new Internet Explorer window opens each time. How can I work around this without touching the Visual Basic application?

A You should read Knowledge Base article 837247, named, appropriately enough, "A link that has a specified target always opens in a new window if Internet Explorer is the startup program in a Terminal Services session or the shell for the operating system". The solution to the problem involves downloading and installing the hotfix at You cannot gain access to linked Web pages from a Web site that you access through a desktop shortcut in Internet Explorer Service Pack 1 and editing the registry.

A You should read Knowledge Base article 837247, named, appropriately enough, "A link that has a specified target always opens in a new window if Internet Explorer is the startup program in a Terminal Services session or the shell for the operating system". The solution to the problem involves downloading and installing the hotfix at You cannot gain access to linked Web pages from a Web site that you access through a desktop shortcut in Internet Explorer Service Pack 1 and editing the registry.

Q I have read that if you have a page that does not write to session state you should set the EnableSessionState attribute of the Page directive to ReadOnly for improved performance. Is this true and why? How can I view this performance impact?

Q I have read that if you have a page that does not write to session state you should set the EnableSessionState attribute of the Page directive to ReadOnly for improved performance. Is this true and why? How can I view this performance impact?

A Consider the following two processes. You issue a GET request for a page with read/write access to session state. You grab the session state object, deserializing as necessary. Then you process the page. Next, you write back to the session state object, serializing it as necessary, and return the response to the client.

A Consider the following two processes. You issue a GET request for a page with read/write access to session state. You grab the session state object, deserializing as necessary. Then you process the page. Next, you write back to the session state object, serializing it as necessary, and return the response to the client.

On the other hand, when you have read-only session state, you issue a GET request for the page, get the session state object, and deserialize it if necessary. Then you process the page and return the response to the client. Therefore, you are saving the writing back steps and also the reserializing steps.

There is also a lock created around the session object when you access it as read/write. This lock is not created with a read-only session. The lock is a session-state-level lock and is held for the entire time the page is processed and until the session state is written back to the server. There is normally not a lot of contention for this lock; however, if you utilize frames you will see the contention start to climb. Once a request detects that it cannot gain an exclusive lock on the session state it goes into a polling process which will poll for the lock every 500 ms. The lock is not used when multiple read-only requests are made for the same session state.

Send your questions and comments to  webqa@microsoft.com.

Thanks to the following developers at Microsoft for their technical expertise: Mark Atherton, Earl Beaman, Ryan Byington, Todd Carter, Doug Cook, Jeff Davis, Mark Flick, Scott Guthrie, Brett Hill, Keith Homiski, Frank Isernhagen, Darren Jefford, Andreas Klein, Jamie Laflen, Francisco Javier Banos Lemoine, Ajay Mansata, Aditi Maheshwari, Ian Parramore, Gang Peng, Shahar Prish, Ahmad Safa, Mike Skovrinskie, Sean Sutherland, Niall Waller , Brad Wilson, and Radomir Zaric.