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?


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:

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)

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.

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.

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?


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>


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:

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?


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.


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.


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.

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.



© 2007 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.