Tải bản đầy đủ - 0 (trang)
ASP.NET MVC Example: the Survey Application Revisited

ASP.NET MVC Example: the Survey Application Revisited

Tải bản đầy đủ - 0trang

CHAPTER 8 ■ Developing Offline Web Applications

Figure 8-6. Survey application converted to an offline application

The modified Survey application is almost identical to the original in terms of look and feel, except for

one change. Below the Submit Answers button, you now display the network status so the user knows

whether survey data can be saved to the database.

Creating a Cache Manifest File

To begin converting the Survey application into an offline application, create a copy of the Survey

application and open it in Visual Studio. Next, you need to create the cache manifest file for the

application. So, create a text file named Survey.cachemanifest, and add the entries shown in Listing 8-12.



CHAPTER 8 ■ Developing Offline Web Applications

Listing 8-12. Survey.cachemanifest File


# version 1.0







/ Home/ErrorPage

Look at this listing carefully. The CACHE section lists four entries: one route URL, one CSS file, and two

script files. The FALLBACK section specifies a generic error page: the ErrorPage view displays a generic error

message to the user.

Next, open index view and specify the cache manifest file using the manifest attribute, like this:


Getting the Questions and Choices

The overall functionality of the Survey application remains unchanged even when it’s converted into an

offline application. However, because the application relies on the questions and choices stored in the

database, you need to cache them on the client side. Recollect that the GetQuestions() and GetChoices()

functions call controller action methods to retrieve questions and choices, respectively. You should store

this data into local storage so it’s also available in offline mode.

■ Note  A real-world survey or online exam application has many questions and choices. Additionally, the

questions may change frequently, and it would be impractical to cache all of them and their choices on the client

side. A better approach is to fetch questions and choices in live mode every time and then inform users that they can

go offline.

The modified versions of the GetQuestions() and GetChoices() functions are shown in Listing 8-13.

Listing 8-13. Storing data in local storage

function GetQuestions() {





error: function (err) {

if (storage[“container”] != null) {



else {

alert(err.status + “ - “ + err.statusText);




CHAPTER 8 ■ Developing Offline Web Applications




function GetChoices() {



else {






error: function (err) {

alert(err.status + " - " + err.statusText);




Notice the bold code. The GetQuestions() function fetches questions and then calls the GetChoices()

function. Once GetChoices() completes successfully, the container
element is populated with

questions and their choices. The code stores the entire dynamically generated HTML markup in local

storage. This way, even if there is no network connectivity, the questions and choices are available to the

code. Beginning the next time through, if GetQuestions() can’t access the database due to network

unavailability, the error function of the $.ajax() call (of GetQuestions()) retrieves the HTML markup

stored in the local storage and populates the container

Checking for a Network Connection

Finally, the Survey application needs to store the answers in a database. It makes an Ajax call to the server

whenever the Submit Answers button is clicked. When the user clicks Submit Answers, the SubmitData()

function is invoked; it calls the SaveResults() controller action method to save the survey data. This Ajax

call succeeds only if there is network connectivity.

It would be beneficial to inform the user about the availability of a network connection and

accordingly enable or disable the Submit Answers button. To do so, you need to periodically check

whether a network connection is available. Listing 8-14 shows how this can be accomplished.

Listing 8-14. Enabling or Disabling the Submit Answers Button

$(document).ready(function () {


setTimeout(CheckOnline, 5000);


function CheckOnline() {


type: "POST",

url: 'Home/IsOnline',

contentType: "application/json; charset=utf-8",

dataType: "json",

success: function (result) {



CHAPTER 8 ■ Developing Offline Web Applications

if (result == true) {

$("#status").html("You are Online!");


setTimeout(CheckOnline, 5000);



error: function () {

$("#status").html("You are Offline!");

$("#submit").attr('disabled', 'disabled');

setTimeout(CheckOnline, 5000);




This code should look familiar: you used a similar technique in the Clock application. Using the

setTimeout() method, you call CheckOnline() every five seconds. CheckOnline() then calls the IsOnline()

controller action method. If this call is successful, it indicates that a network connection is available;

otherwise, the network is unavailable. Accordingly, the Submit Answers button is enabled or disabled by

adding or removing the disabled attribute. IsOnline() is shown in Listing 8-15.

Listing 8-15. IsOnline() Action Methodpublic JsonResult IsOnline()


return Json(true);


IsOnline() returns true in JSON format. You can now run the Survey application and test it by

stopping the application in IIS Express, as explained earlier.


Most web applications need a live network connection to the web server in order to function properly.

Such applications involve heavy interaction between client and server. Some web applications, however,

can work without an active network connection to the web server. Such applications usually involve heavy

client-side functionality. HTML5 allows you to develop such offline applications easily. Not every

application is a good candidate, but if the need arises, you have native support for such offline


At the heart of an offline application is a cache manifest file that lists all the files that are needed in

offline mode. If required, an offline application can connect with the web server when a network

connection is available and transfer data or execute server-side code. The applicationCache object

introduced in HTML5 represents an offline application cache and helps you to track various application

life cycle events by raising events.

HTML5 adds rich client-side capabilities to your web applications. Another such area is client-side file

access. Traditionally, JavaScript couldn’t access local files in any manner. The HTML5 File API provides a

standardized way to deal with local files. The next chapter discusses this feature in detail.



chapter 9


Dealing with Local Files Using

the File API

It’s a well-known fact that for the sake of security and privacy, browsers don’t allow web applications to

tamper with the local file system. Local files are used in a web application only when the user decides to

upload them to the server using the HTML element of type file. The title of this chapter may

surprise you at first, because the term File API gives the impression of being a full-blown file-system

manipulation object model like the System.IO namespace of .NET Framework. Obviously, the people

behind HTML5 are aware of the security issues such an object model can create. So, the File API is

essentially a cut-down version of a file-handling system in which files can only be read and can’t be

modified or deleted. Additionally, the File API can’t read any random file on the machine. File(s) to be read

must be explicitly supplied by the user. Thus, the File API is a safe way to read and optionally upload local

files with user consent.

This chapter examines what the File API can do for you and how it can be used in ASP.NET web

applications. Specifically, you learn the following:

Classes available as a part of the File API

Techniques of selecting files to be used with the File API

Using HTML5 native drag-and-drop

Reading files with the File API

Uploading files to the server

Understanding the File API

The HTML5 File API consists of a set of three objects (see Table 9-1) that allow you to read files residing on

the client computer. The files to be read must be explicitly selected by the user using one of the supported

techniques discussed in later sections. Once selected, you can read the files using JavaScript code.



chapter 9 ■ Dealing with Local Files Using the File API

Table 9-1. Objects Exposed by the File API




A list of files selected by the user. A user typically selects files using a file field or by dragging

from Windows Explorer and dropping them on a predefined area of a web page.


A single file that’s used to find information such as file name, size, and MIME type.


Allows you to read a file in asynchronous fashion. Once read, you can either upload the

contents to the server or use them for custom processing.

The object model of the File API is quite small, but you can use these three objects in creative ways

that were impossible (or at least very difficult) prior to HTML5. Some of the creative ways in which you can

use the File API are as follows:

In traditional HTML, when you use a file field to upload files, there is no checking of

file size on the client end. Only when the file reaches the server can you perform

checks in the server-side code and accept or reject the file. You can now reject files

above a certain file size at the client.

You can read image files on the client side and render a preview or thumbnail before

they’re uploaded to the server. Such a facility can also be used in social networking

applications or photo album applications that deal with images.

You can validate the content of file before it’s uploaded to the server. For example, if

your application is supposed to upload XML files, you can validate an XML

document before it reaches the server.

You can develop client-side images or file catalogs that a user can review before

finally uploading them to the server.

You can develop a photo album application that lets the user drag and drop images

files rather than individually picking them up.

■ Note  In the future, HTML5 may add more support for file-system navigation. A draft specification is available at

http://dev.w3.org/2009/dap/file-system/pub/FileSystem/. However, as of this writing there is little or

no support for these features in the leading browsers.

FileList Object

The FileList object represents a list of File objects. A FileList is returned either from a file field (
type="file">) placed on a web page or by the user dragging and dropping local files from Windows Explorer

on a droppable area of a web page. Normally, you iterate through a FileList to access individual File

objects. The FileList object exposes just one property and one method, as described in Table 9-2.

Table 9-2. Properties and Methods of the FileList Object

Property / Method



The length property returns a number of File objects from a FileList.


The item() method accepts a zero-based index and returns a File object at that




chapter 9 ■ Dealing with Local Files Using the File API

File Object

A File object represents a single file and provides information about it such as its name, size, and MIME

type. You also need a File object if you wish to read the contents of a file. Table 9-3 lists the properties of

the File object.

Table 9-3. Properties of the File Object




Name of a File along with its extension


Size of a file in bytes


MIME type of the file

FileReader Object

A FileReader object allows you to read the contents of a File. The read operation is performed in

asynchronous fashion. This way, even very large files can be read without blocking other operations. The

FileReader object can read File contents as text, Base64, binary, or ArrayBuffer. Table 9-4 lists the

methods of the FileReader object that are responsible for reading a file.

Table 9-4. Methods of the FileReader Object

Property / Method



Reads a file as a text file


Reads a file as a data URL (Base64)


Reads a file as a raw binary string


Reads a file as an ArrayBuffer


Can be used to abort a file-reading operation

The readAsText() method is intended to be used with text-based files such as plain-text files, CSV

files, and XML files. The readAsDataURL() method encodes the file content in Base64 format and returns it

as a data URL. As described in more detail in Chapter 4, you know that the data URL format consists of

Base64-encoded data prefixed with the MIME type of the file, as shown in the following example:


The readAsDataURL() method also comes in handy in situations where binary data can’t be transferred

to the server. One such situation is the jQuery $.ajax() method that sends text data to the server. The

readAsBinaryString() method reads files as raw binary data. The readAsArrayBuffer() method reads the

file contents as an ArrayBuffer; an ArrayBuffer is a fixed-length binary data buffer.

The file-reading methods discussed here affect certain properties of a FileReader. These properties

can then be used to process the file contents or to flag an error to the end user. Table 9-5 lists these




chapter 9 ■ Dealing with Local Files Using the File API

Table 9-5. Properties of the FileReader Object




Error that occurred (if any) while reading a file.


State of a FileReader object. The possible readyState values are 0 (EMPTY), 1

(LOADING), and 2 (DONE).


File’s contents. This property is valid only after the read operation is complete.

The format of the data returned depends on the read method invoked.

The FileReader raises certain events as the file is being read. You can wire up handlers for these events

and intercept various stages of the read operation. The events raised by the FileReader object are given in

Table 9-6.

Table 9-6. Events of the FileReader Object




Raised when a file is successfully read


Raised when the reading of file content is about to begin


Raised when the file-reading operation completes successfully or with an



Raised periodically when data is being read


Raised when there is some error while performing the read operation


Raised when a read operation is aborted

Out of all the events listed in Table 9-6, you must handle the load event because that is where you can

access the file content.

Selecting Files to Be Used With the File API

As mentioned previously, files to be accessed using the File API must be explicitly selected by the user in

one of the following ways:

A user can select files using the Open File dialog shown by a file field control.

As user can drag files from Windows Explorer and drop those files on some

predefined area of a web page.

The first way is straightforward and traditional. A variation on this technique is to display the Open

File dialog without a visible file field on the page. In such cases, you need to play tricks to achieve the

desired behavior. The second way is specific to HTML5, and with the native support for drag-and-drop it’s

easy to implement in web pages.

The following sections discuss these two ways of selecting files. Note that HTML5 drag-and-drop

features aren’t restricted to file selection alone and can be used independently in your applications.

Using a File Field to Select Files

Using a file field to select one or more files is the most basic technique of selecting files to be used with the

File API. Prior to HTML5, a file field control allowed the selection of only one file at a time. If you wanted to



chapter 9 ■ Dealing with Local Files Using the File API

allow users to select five files, you had to place five separate file field controls on the web page. In HTML5,

however, users can select multiple files using a single file field control. This is possible with the new

multiple attribute of the element. Listing 9-1 shows how a file field control can be configured for

selecting a single and multiple files.

Listing 9-1. File Field Control Markup

This listing shows two elements with the type attribute set to file. Notice that the second file

field has the multiple attribute. When you specify the multiple attribute, the resulting Open File dialog

allows you to select multiple files using standard Windows techniques (a combination of the Ctrl/Shift key

and mouse clicks).

The file fields are displayed differently by different browsers. For example, Figure 9-1 shows how the

file fields are displayed in Chrome, Opera, and Firefox.

Figure 9-1. File fields in different browsers



chapter 9 n deaLing with LocaL fiLes using the fiLe api

Notice how Chrome and Opera show the file field with the multiple attribute to indicate that multiple

files can be selected. Clicking the Browser, Choose Files, or Add Files button opens a standard Windows

Open dialog, as shown in Figure 9-2.

Figure 9-2. Selecting multiple files using the Open dialog

Notice that Figure 9-2 shows multiple files selected. When you select multiple files and click the Open

button in the Open File dialog, all the selected files are added to the same file field, one after the other.

Firefox and Opera display all the selected files in the text box of a file field control, whereas in Chrome you

need to hover your mouse over the file field to see a list of selected files (see Figure 9-3).

Figure 9-3. File field control after selecting files



chapter 9 ■ Dealing with Local Files Using the File API

If you’re developing an ASP.NET Web Forms–based application, you can use the FileUpload server

control instead of using the raw markup shown in Listing 9-1. The markup in Listing 9-2 shows how you

can use FileUpload server controls.

Listing 9-2. Using FileUpload Server Controls

The first FileUpload server control shown here lets you select a single file. The second FileUpload

server control has its AllowMultiple property set to True and allows you to select multiple files.

If you’re developing an ASP.NET MVC application, you can either use the plain HTML shown in Listing

9-1 or use an HTML TextBox helper to render a file field. Listing 9-3 shows how to use HTML TextBox

helpers to render file fields.

Listing 9-3. Using TextBox Helpers to Render File Fields

<% using (Html.BeginForm("Index","Home","POST")) { %>

<%= Html.TextBox("file1", "",new {type="file"})%>

<%= Html.TextBox("file2", "",new {type="file",multiple="multiple"})%>


As you can see, to render a file field you use TextBox helper and supply a type property value of file.

The first call to the TextBox helper renders a file field that allows only one file to be selected, whereas the

second call sets the multiple property to allow multiple files to be selected.

Using a Custom Button to Select Files

Sometimes, using a file field to select files is undesirable for aesthetic reasons. Although you can use CSS to

change the look and feel of a file field, its appearance can’t be altered drastically. For example, let’s say you

wish to display an image on a web page, and when a user clicks the image you wish to prompt them to

select one or more files. Something like this is impossible using file field because even after applying CSS,

the field’s basic appearance is governed by the browser.

If you wish to provide such a custom technique for selecting files in your application, you need to use a

programmatic trick. You essentially need to add a file field to the web page but keep it hidden from view.

When a user clicks a custom graphic or button intended for file selection, you trigger the click event on

the hidden file field through JavaScript. This way, the Open File dialog is displayed to the user. Once the

user selects one or more files, those files are assigned to the hidden file field. You can then access the files

for further processing.

Figure 9-4 shows a custom image for selecting files.



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

ASP.NET MVC Example: the Survey Application Revisited

Tải bản đầy đủ ngay(0 tr)