Sending Downloading Files

It's important for you to understand that only the client can initiate a file download. You can't write VB.NET code that downloads a file. For Web applications, it's best to forget the term "downloading" or at least, whenever you hear it, twist it in your head so that you think, "Get the client to request the file."

When you approach downloading from the client point of view, it becomes obvious that there are many ways to get the client to request the file. The most common method is to provide a link. For example, the following link will download the text file FileStaticMethods.zip that you can find in the csharpASP\chl0 folder on www.sybex.com. Either use the code below or run chl0-8.aspx. You may need to adjust the URL to match your server. Watch for unwanted line breaks in the following URL.

<a href="http://localhost/CSharpASP/ch10/ FileStaticMethods.zip"> Download FileStaticMethods </a>

When users click the link in IE, they'll see the File Download dialog (see Figure 10.5).

Figure 10.5: The IE 6 File Download dialog

In IE, two dialog boxes actually are open at this point, but the second dialog is hidden behind the File Download dialog. After users select one of the options on the topmost dialog, those who choose the Save option will have an option to save the file. Otherwise, they go directly to this background File Download dialog, which shows a download progress bar. In Figure 10.6, I've dragged the Save As dialog partially out of the way so you can see both dialogs.

Figure 10.6: The background IE 6 File Download dialog (progress dialog)

Figure 10.6: The background IE 6 File Download dialog (progress dialog)

As you've seen, it's easy to create a link that downloads a file, but that may not suit your interface requirements. What if you want to use a button rather than a link? Don't be fooled by the LinkButton control's name—it acts like a button, not a link, so you don't want to use that. What if you want to use an image, or a selection from a ListBox? You need to write a little client-side script to use these controls to download a file. You haven't seen any client-side script so far in this book, and I'm not going to explain it here, so you'll have to take it at face value for now. Nevertheless, it's going to get a little more complicated than you might like. Bear with me.

For any control type except a HyperLink, you call a method in a client-side script to request the file. The event you use to fire the script depends on the control. For example, you would use the onclick event for button or image controls, and the onchange event for ListBoxes or DropDownList controls.

The problem is that when you use Web Forms server controls, some events don't fire on the client—they fire on the server. Fortunately, you can work around this easily. When you need to write client-side script to handle an event and that event is one that ASP.NET handles on the server, one solution is this: Don't use a Web Form server control; use an HTML control instead. I'll show you another method in Chapter 20, "Leveraging Browser Clients."

Drag the appropriate HTML control onto your Web Form and set its properties. When you're ready to code the client script, switch to HTML mode. Find the appropriate control tag and insert an attribute for the event you want to respond to. The attribute's value is the name of a function to run when the event occurs—it's a function pointer, in other words.

I recommend you try writing at least one client-side script before you continue. To write a client-side script, create a Web Form and add an HTML Button control to the page. Then, switch to HTML mode, find the Button control tag—it will be an <input> control with a type="button" attribute—and add an onclick="getFile()" attribute and value (see Listing 10.6).

Paste the <script> tag from Listing 10.6 into the HTML. It's best to put the script inside the <head> section. Then run the Web Form.

Listing 10.7 contains a slightly more complex example. The Web Form ch10-8.aspx (see Figure 10.7) contains three different controls: a HyperLink, an HTML Button, and a ListBox, all of which download the

FileStaticMethods.zip file.

Figure 10.7: Downloading files using various controls

Listing 10.7: HTML Code for the ch10-8.aspx File (ch10-8.aspx)

<%@ Page Language="vb" AutoEventWireup="false" Codebehind="ch10-8.aspx.cs" Inherits="CSharpASP.ch10_8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0

Transitional//EN"> <HTML> <HEAD>

<meta name="GENERATOR"

content="Microsoft Visual Studio.NET 7.0"> <meta name="CODE_LANGUAGE" content="Visual Basic 7.0"> <meta name="vs defaultClientScript" content="JavaScript"> <meta name="vs targetSchema"

content="http://schemas.microsoft.com/intellisense/ie5"> </HEAD>

<body MS_POSITIONING="GridLayout">

<form id="Form1" method="post" runat="server"

language="javascript"> <asp:HyperLink id="HyperLink1" style="Z-INDEX: 101; LEFT: 16px; POSITION: absolute; TOP: 18px" runat="server"

Width="272px" Height="17px" Target="_blank" NavigateUrl="FileStaticMethods.zip">Download FileStaticMethods</asp:HyperLink>&nbsp; <INPUT style="Z-INDEX: 103; LEFT: 15px; WIDTH: 87px; POSITION: absolute; TOP: 75px; HEIGHT: 21px" type="button" value="Get File..." onclick="getFile('FileStaticMethods.zip')"> <asp:ListBox id="ListBox1" style="Z-INDEX: 104; LEFT: 13px; POSITION: absolute; TOP: 122px" runat="server" Height="102px" Width="344px"

onchange="getFileFromList(this)"></asp:ListBox> </form>

<script language="javascript">

function getFile(fname) { window.navigate(fname);

function getFileFromList(aList) {

var fname = aList.options[aList.selectedIndex].text window.navigate(fname);

In this example, the button onclick event passes the filename FileStaticMethods.zip to the getFile() function. When the user clicks the button, the browser calls the highlighted getFile() function in the <script> tag at the end of Listing 10.7. The function commands the current browser window to request (navigate) to the filename passed in the fname parameter.

As an aside, you can navigate to any valid URL using the window.navigate method. In other words, the result is the same as when you use the Response.Redirect method on the server (although that's not exactly how the Response.Redirect method works—see Chapter 6 for details). When you request a URL that returns HTML or some other MIME type that the browser understands, it displays the contents of the file. For all other files, such as the zip file in this example, the browser displays a dialog asking if you want to open the file or save it to disk. If you choose to open the file, the browser will try to run the application associated with the file's extension (or the appropriate Helper application in Netscape browsers). Note that the unrecognized file type doesn't cause the browser to clear the current page.

If you were to use a DropDownList or a ListBox rather than an HTML button, you would use the onchange event. The onchange event is not handled on the server, so you can add the event attribute to the <asp:ListBox> tag.

Note If you decide to use an HTML ListBox or DropDownList instead, remember that those controls are <select> tags in HTML.

The ListBox code in Listing 10.7 contains the attribute and value onchange="getFileFromList (this)".

<asp:ListBox id="ListBox1" style="Z-INDEX: 104; LEFT: 13px; POSITION: absolute; TOP: 122px" runat="server" Height="102px" Width="344px"

onchange="getFileFromList(this)"></asp:ListBox>

The this parameter is an object reference to the ListBox control itself, meaning that when the user clicks an item in the list, the onchange event fires, and the page calls the getFileFromList function, passing the select list input control to the function.

First, the script retrieves the selected list item. An HTML select control has an indexed collection of options, each one of which has text and value properties. In that case, you want to retrieve the text property. You can determine the selected item with the selectedIndex property.

function getFileFromList(aList) {

var fname = aList.options[aList.selectedIndex].text window.navigate(fname);

After retrieving the selected item text and assigning it to the variable fname, the script uses the window.navigate method to request the file—exactly the same code as the button onclick event uses.

As a final note to this topic, there are other ways to write the client-side script. In fact, you can pass the selected item directly by using this attribute and value in the <select> tag:

onchange="getFile(this.options[this.selectedIndex].text)"

The preceding code calls the same function as the button onclick event. By writing the code this way, you could eliminate the need for two separate scripts.

Was this article helpful?

0 0

Post a comment