AskthePRO
LANGUAGES: C#
ASP.NET VERSIONS: 1.0 | 1.1
Get the Lowdown on Cache
Also, learn how to display modal data-entry dialogs in an ASP.NET app, and why ASP.NET limits the size of file uploads.
By Jeff Prosise
Q: I'm using ASP.NET application cache to cache DataSets containing database query results. I'm also using cache removal callbacks to refresh the cache when ASP.NET removes a DataSet from it. I store a reference obtained from HttpContext.Cache in a static field so I'm able to access the cache during a cache removal callback. However, the results seem random. Sometimes calling Cache.Insert using the stored reference works, and sometimes it doesn't. What am I doing wrong? Is it not possible to call Cache.Insert from a cache removal callback?
A: Cache.Insert can be called anywhere, anytime, but when you call it during a cache removal callback, it's important to use a reference obtained from HttpRuntime.Cache rather than HttpContext.Cache. This code works fine in a cache removal callback handler:
HttpRuntime.Cache.Insert ("MyDataSet", ds, ...
new CacheItemRemovedCallback (MyHandler));
But this code is unreliable:
// In Application_Start or elsewhere
_Cache = HttpContext.Current.Cache;
...
// In a cache removal callback handler
_Cache.Insert ("MyDataSet", ds, ...
new CacheItemRemovedCallback (MyHandler));
Another nuance of the application cache is that CacheDependency objects passed in Cache.Insert's third parameter can't be recycled. If you use cache dependencies, be sure to create a new CacheDependency object each time you call Cache.Insert.
Q: How can I display modal data-entry dialogs in an ASP.NET application?
A: Modal dialogs can be displayed in Internet Explorer 4.0 and higher by calling window.showModalDialog from client-side script. Displaying a modal dialog is easy enough, but there's a bit of trickery involved in closing the dialog in response to a button click and preventing a postback in the dialog from opening a new browser window.
I've included three files that demonstrate one way to implement modal dialogs in ASP.NET apps (see Figures 1, 2, and 3). To see them in action, copy all three to a virtual directory on your Web server, then open ModalDialog.aspx in your browser and click on the Log In button. In response, a modal dialog appears (see Figure 4). Type a name into the User Name box and type "imbatman"(lowercase) into the Password box. Finish up by clicking on the dialog's Log In button. The dialog disappears and the name you entered replaces the Log In button in the main browser window.
Figure 1. ModalDialog.aspx contains a button that pops up a modal login dialog. Once the user has logged in, a personalized greeting replaces the button.
Figure 2. Login.aspx provides the login form that appears in the modal dialog.
Figure 3. ModalDialog.aspx invokes this page, LoginDialog.aspx, by calling showModalDialog. An
Figure 4. When you click on the Log In button in ModalDialog.aspx, a modal user name/password dialog pops up.
So how does it work? The starting point is ModalDialog.aspx's Page_Init method, which creates the Log In button that's visible when the page first appears in the browser window. The button includes a DHTML onclick attribute that calls a local JavaScript function named onPopup. onPopup is implemented in a client-side script block that Page_Init adds to the page by calling Page.RegisterClientScriptBlock. Do a View Source after pulling up ModalDialog.aspx and you'll see the script block returned to the browser:
Clicking the Log In button calls doPopup, which in turn calls window.showModalDialog to display a modal dialog. Following a successful log in, showModalDialog returns 1 and doPopup returns true. If the user dismisses the dialog by clicking the X in the upper-right corner, showModalDialog returns undefined and doPopup returns false. Because doPopup's return value doubles as the onclick handler's return value, ModalDialog.aspx posts back to the server if the user logs in successfully - but suppresses the postback if the user does not. If a postback occurs, ModalDialog.aspx's Page_Init method replaces the Log In button with a LiteralControl echoing what the user typed into the user name box. It extracts the user name from session state (again, see Figure 1).
The Web form that appears in the login dialog comes from Login.aspx (again, see Figure 2). Clicking the form's Log In button posts back to the server and activates the OnLogIn method. If OnLogIn determines that the login is valid (that is, if the user typed "imbatman" into the password box), it writes the user name to session state and closes the dialog by returning a client-side script block that calls window.close. The script, which is added to the page with Page.RegisterStartupScript, also sets showModalDialog's return value to 1 to indicate a successful login. The client-side script looks like this:
If, on the other hand, the login is unsuccessful, OnLogIn writes back to the page a block of client-side script that reports the error in a popup message box:
In real life, OnLogIn could easily perform a more rigorous validation of the user name and password (for example, it could check them against a security database) because it's a server-side method.
The final piece of the puzzle is LoginDialog.aspx (see Figure 3). ModalDialog.aspx doesn't activate Login.aspx directly; instead, it activates LoginDialog.aspx, which in turn loads Login.aspx in an
Granted, the code that does modal dialogs in ASP.NET isn't pretty, but that's the trade-off when you want to build rich user interfaces with HTML.
Q: I'm using an ASP.NET file upload control () to upload images to an intranet server. Uploads work fine with small and medium-sized images, but fail with large ones. Does ASP.NET limit the size of file uploads? If so, how does one increase the permissible upload size?
A: ASP.NET indeed limits the size of file uploads, in part to thwart denial-of-service attacks seeking to overwhelm servers with gargantuan file uploads. The default maximum upload size is 4 MB. You can change that by editing Machine.config or a local Web.config file.
I've included an excerpt from a Machine.config file that
has been modified to increase the 4 MB size limit to 8 MB (see Figure 5). The
key is the
executionTimeout="90" maxRequestLength="8192" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100" /> Figure 5. Setting
maxRequestLength to 8192 in Machine.config increases to 8 MB the maximum size
of files uploaded to the server. Changing maxRequestLength in Machine.config modifies the
permitted upload size for all ASP.NET applications on the Web server. You can
increase (or decrease) the maximum upload size for an individual application
and even for individual subdirectories within an application by specifying a
maxRequestLength setting in a local Web.config file. If it's placed in a
virtual root directory, this Web.config file increases the file upload size for
the application in that directory without affecting other applications on the
server: The sample
code referenced in this article is available for download. Jeff Prosise is the author of several books, including Programming Microsoft .NET
(Microsoft Press, 2002). He's also a co-founder of Wintellect (http://www.wintellect.com), a software
consulting and education firm that specializes in .NET. Have a question for
this column? Submit queries to editors@devproconnections.com.