Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ASP.NET 2.0 Instant Results

.pdf
Скачиваний:
67
Добавлен:
17.08.2013
Размер:
11.03 Mб
Скачать

Greeting Cards

Figure 11-6

All of the other methods are listed in the following table. Because most of these methods have long argument lists, the table lists only the name of the method and not its arguments and their types. Refer to the section “Code and Code Explanation” later in this chapter for a description of these parameters, or look in the code for the Imaging class at the XML comments that are placed in front of each of the methods. These comments describe the purpose of each method and its parameters.

Method

Return Type

Description

 

 

 

AddTextToImage

n/a

This method is capable of adding text on top of an

 

 

image at a specified location and in a specific font

 

 

and color. This method has one additional overload.

CropImage

n/a

Crops an image passed to this method to a specified

 

 

region. This method has one additional overload.

DrawRectangle

n/a

Draws a rectangle on top of an image. This method

 

 

has one additional overload.

GetColors

Color()

Returns an array of Color objects. This method can

 

 

return either all known colors, or return a list with-

 

 

out the system colors such as ActiveBorder or

 

 

WindowText.

GetFontFamilies

FontFamily()

Returns an array of FontFamily objects for the

 

 

machine where this method is called.

GetImageFormat

ImageFormat

Returns the format of the image passed to

 

 

this method, such as ImageFormat.Jpeg,

 

 

ImageFormat.Png, and so on.

GetImageHash

String

Calculates the hash of an image. This method is

 

 

useful for comparing two images. Because

 

 

generating a hash always returns the same value for

 

 

identical data, you can compare two images through

 

 

code without looking at them.

 

 

Table continued on following page

357

Chapter 11

Method

Return Type

Description

 

 

 

GetImageSize

Size

Returns the size of an image in pixels as a Size

 

 

object.

GetRotateTypes

String()

Returns a list with the available rotating types as a

 

 

String array. The array includes types like

 

 

Rotate90FlipNone to indicate a rotation of 90

 

 

degrees clockwise.

ResizeImage

n/a

Resizes an image to the specified size or to a maxi-

 

 

mum height or width. This method has five addi-

 

 

tional overloads.

RotateImage

n/a

Rotates and flips an image in the specified direction.

 

 

This method has one additional overload.

 

 

 

Not all of these methods are used in the Greeting Cards application. GetImageHash and GetImageFormat are not used at all, but because they could be very useful in other applications, they have been included in the Toolkit anyway. Refer to the accompanying code for more details on these methods.

Most of the overloads that work with an image expect the names of the source and target files as a string. For example, the signature for the CropImage looks like this:

Public Shared Sub CropImage(ByVal fileNameIn As String, ByVal fileNameOut As

String, ByVal theRectangle As Rectangle)

The parameter fileNameIn determines the source file, and fileNameOut defines the file the cropped image should be saved to. To make it easier for you to overwrite an existing file without specifying the same name of the file twice in your code, these methods have an overload that has almost the same signature but without the fileNameOut parameter. Internally they call the overloaded version, passing it the same name for both the parameters. The following code snippet shows the implementation of the CropImage method that calls an overload:

Public Shared Sub CropImage(ByVal fileNameIn As String,

ByVal theRectangle As Rectangle)

CropImage(fileNameIn, fileNameIn, theRectangle)

End Sub

With this method, external code needs to pass the filename only once and the method ensures that the source file is overwritten automatically with the new and cropped image.

The UploadHandler Class

The UploadHandler class is a simple yet very powerful class used to make uploading files in an ASP.NET application a lot easier.

Usually, when you upload a file, you perform all kinds of checks on the uploaded file. For example, you may try to find out if the user uploaded a file at all, and whether it has the required extension. The

UploadHandler class can handle this for you. All you need to do in the code-behind of a page is create a new instance of the UploadHandler, set a few properties (most of them have sensible defaults), and call

358

Greeting Cards

UploadFile and pass it an instance of an <asp:FileUpload> control. Figure 11-7 lists all the methods and properties of this class.

Figure 11-7

Before you can work with the UploadHandler class, you need to create an instance of it. That’s why it has a public default constructor. Once you have an instance of the class you have to set at least the VirtualSavePath property; all the other properties are optional. The following table describes the seven properties of the UploadHandler class:

Property Name

Type

Default Value

Description

 

 

 

 

AllowedExtensions

String

String.Empty

Gets or sets a regular

 

 

 

expression to use when

 

 

 

checking file extensions.

 

 

 

For example,

 

 

 

^.jpg|.gif$ allows

 

 

 

only JPG or GIF files. If

 

 

 

this property is not set,

 

 

 

all extensions are

 

 

 

allowed.

Extension

String

String.Empty

This read-only property

 

 

 

returns the extension of

 

 

 

the uploaded file.

FileName

String

String.Empty

Gets or sets the name

 

 

 

of the file (without

 

 

 

extension) as it should

 

 

 

be saved.

 

 

 

Table continued on following page

359

Chapter 11

Property Name

Type

Default Value

Description

 

 

 

 

GenerateDateFolder

Boolean

False

Determines whether

 

 

 

subfolders are created for

 

 

 

the current year and

 

 

 

month to store the file in.

 

 

 

This is useful when you

 

 

 

have a lot of uploaded

 

 

 

files and want to store

 

 

 

them in logical folders.

GenerateUniqueFileName

Boolean

False

Determines whether the

 

 

 

file gets a unique name.

 

 

 

When set to True, the

 

 

 

property FileName is

 

 

 

ignored and the file is

 

 

 

saved with a GUID as

 

 

 

its name.

OverwriteExistingFile

Boolean

False

Determines whether

 

 

 

existing files should be

 

 

 

overwritten when they

 

 

 

already exist.

VirtualSavePath

String

n/a

Gets or sets the virtual

 

 

 

path to the folder where

 

 

 

the uploaded files should

 

 

 

be saved. This property

 

 

 

is updated when

 

 

 

GenerateDateFolder is

 

 

 

True.

 

 

 

 

Once these properties have been set, your code should call the class’s only public method UploadFile and pass it an instance of an <asp:FileUpload> control. This method carries out some checks using the private FileExists and IsExtensionAllowed methods and then either saves the uploaded file to disk or throws an exception. The following table describes the three methods (other than its constructor) of the UploadHandler class:

Method

Return Type

Description

 

 

 

FileExists

Boolean

Returns True when a file with the same name

 

 

already exists.

IsExtensionAllowed

Boolean

Returns True when the extension of the

 

 

uploaded file meets the criteria set in the

 

 

AllowedExtensions property.

UploadFile

n/a

This method is the workhorse of the

 

 

UploadHandler class. It performs a number

 

 

of checks on extensions, paths, and so on,

 

 

and then saves the file to disk or throws an

 

 

exception.

 

 

 

360

Greeting Cards

You see a lot more of the inner workings of this class in the section “Code and Code Explanation.”

In addition to the Toolkit folder, the App_Code folder contains two helper classes, which are discussed next.

Helper Classes

The two helper classes for the Greeting Cards application, called FileHandlingEventArgs and AppConfiguration, have been put in the App_Code folder directly. The reason for this is that they are used by the web application, and not by the code in the Toolkit. The design of these classes is discussed next. You see how and where they are used in the section “Code and Code Explanation.”

The FileHandlingEventArgs Class

The four user controls that make up the largest part of the user interface of the application are all capable of firing an event called ImageFinalized to signal to the application that they’re done with their work. When they fire this event, they pass up an instance of the FileHandlingEventArgs class that inherits from the standard System.EventArgs class. The FileHandlingEventArgs has the same behavior as this EventArgs class, but adds an additional property called FileName, as you can see in Figure 11-8.

Figure 11-8

This FileName property holds the name of the image that the user control has been working with. The constructor for this class accepts this filename and stores it in a private backing variable that is made accessible through the public FileName property. You see how this works later when the code for the user controls is discussed.

The final class in the App_Code folder is AppConfiguration, the configuration class you also saw in previous chapters.

AppConfiguration

The AppConfiguration class is a simple wrapper with five public properties around application settings keys in the Web.config file. This class is used in some of the user controls in the site to determine the maximum height or width of an image, the path where the uploaded images should be saved, and the name and e-mail address used to send out e-mails. Figure 11-9 shows these five properties.

The two Email properties hold the e-mail address and name of the sender of the e-mails that are sent by the application.

361

Chapter 11

Figure 11-9

The MaxImageHeight and MaxImageWidth properties work together and determine the new maximum height or width of the image that is uploaded. The user control that uploads and saves the image in the first step of the Greeting Card generator automatically resizes the image so its dimensions fit between these two maximum properties. You see how the image is resized later.

The TempImagesFolder property holds the virtual path to a folder in your site where temporary images are stored. The Web.config file for the application sets this value to ~/Images/Temp, but you can change that so it points to a different folder.

Now that you have seen the design of the classes in the Toolkit and their methods, it’s time to look at the actual implementation of these classes and the user interface of the web site. The next section explains how the web site is set up using a single web page and four user controls and how these controls and the page interact.

Code and Code Explanation

Although the code in the Toolkit is already very reusable, the entire application has been made even more generic and reusable by implementing the various actions on the image inside four user controls. Each of these controls can be used separately in a different application and has no dependencies on the host page or any of the other user controls.

In the case of the Greeting Cards application, these four controls have been added to a host page located in the root of the site. This page serves as a controller to orchestrate the actions of the various user controls. In the next section, you see how this host page is able to communicate with the four user controls. After that, each of the four controls is discussed in more detail separately.

The Host Page

The host page, called Default.aspx, contains a reference to each of these four controls in an <asp:MultiView> control. The host page is responsible for displaying the right user control at the right time, allowing the user to sequentially progress through the Greeting Cards application. The code in the code-behind file takes the user through the following five steps:

362

Greeting Cards

1.

2.

3.

4.

5.

Select an image and upload it to the server.

Optionally rotate or flip the image.

Optionally crop the image to a user-defined region of the image.

Add text to the image at a user-defined location.

Send an e-mail with the image as an embedded object.

The first four steps are carried out by user controls, whereas step 5 takes place in the code-behind of the host page itself. Figure 11-10 shows these five steps. The outer rectangle represents the host page, and the smaller inner rectangles represent the four user controls.

SelectImage.ascx

RotateFlipImage.ascx

1

2

AddText.ascx

CropImage.ascx

4

3

5

 

Send Email

 

 

Default.aspx

Figure 11-10

 

363

Chapter 11

Inside the Controls folder in the root of the web site you find the four user controls mentioned in Figure 11-10. The following table lists each of these controls and describes their purpose:

Control Name

Description

 

 

SelectImage.ascx

Allows a user to select an image from the local hard drive and upload it

 

to the server where it is stored on disk. The uploaded image is resized

 

automatically to meet the maximum height and width rules set in the

 

Web.config file.

RotateFlipImage.ascx

This control allows a user to rotate or flip an image. Rotating and

 

flipping is optional.

PictureCropper.ascx

With this control a user can select a portion of an image by cropping the

 

original image. Cropping is optional.

AddText.ascx

This control allows a user to add text to the image at an arbitrary

 

location. The user is free to choose from a list of font families and sizes

 

and specify the color of the text.

 

 

Inside the host page, these four controls have been added to a View control inside a MultiView like this:

<asp:MultiView ID=”MultiView1” runat=”server” ActiveViewIndex=”0”> <!-- Other views go here -->

<asp:View ID=”View2” runat=”server”> <!-- View specific markup goes here -->

<Wrox:SelectImage ID=”SelectImage1” runat=”server” /> </asp:View>

<asp:View ID=”View3” runat=”server”> <!-- View specific markup goes here -->

<Wrox:RotateFlipImage ID=”RotateFlipImage1” runat=”server” /> </asp:View>

<!-- Other views go here --> </asp:MultiView>

This code snippet shows two of the user controls in the highlighted lines; the one used to select and upload an image and the one to rotate or flip the image. Because with a MultiView control only one view can be active and thus visible at any given time, the host page shows only one user control at a time.

Because the host page is responsible for displaying the user controls in the right order, it has to know when to load which user control at which time. Because there are no dependencies between the user controls or between a user control and the host page, the Greeting Cards application uses an eventdriven mechanism to determine when a specific control is done with its work. Each of the controls defines an event called ImageFinalized of type ImageFinalizedEventHandler:

Public Delegate Sub ImageFinalizedEventHandler(ByVal sender As System.Object, _ ByVal e As FileHandlingEventArgs)

Public Event ImageFinalized As ImageFinalizedEventHandler

364

Greeting Cards

Whenever a control is ready, it raises the event by calling RaiseEvent and passing it an instance of the FileHandlingEventArgs class you saw earlier. This EventArgs class exposes a property called FileName that holds the location of the image that has been processed by the control.

To see how this works, look in the code-behind for the SelectImage control that you find in the Controls folder in the root of the site. Near the end of the file, you’ll see the following code, which gets triggered when the user clicks the Finish button on the control:

Protected Sub btnFinish_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles btnFinish.Click

RaiseEvent ImageFinalized(Me, New FileHandlingEventArgs(FileName)) End Sub

This raises the event ImageFinalized and passes it a reference to itself using the Me keyword. It also passes the name of the file that has been uploaded using the public FileName property. Inside the codebehind for the host page, this event is caught and handled with the following code:

Protected Sub SelectImage1_ImageFinalized(ByVal sender As Object, _

ByVal e As FileHandlingEventArgs) Handles SelectImage1.ImageFinalized MultiView1.ActiveViewIndex = 2

RotateFlipImage1.FinishButtonText = “Next”

RotateFlipImage1.FileName = e.FileName

End Sub

The first thing this code does is change the ActiveViewIndex of the MultiView control so it displays the next user control — RotateFlipImage1 in this example. It then sets the FinishButtonText property of that control to Next. This determines the text that is displayed on the Finish button of the RotateFlip user control. This is useful if you want to reuse only a few of the user controls in your application or want to reorder them. All but the last control can then be set up to display Next, and the last control could have the text Finish on the button. If you only reuse a single user control, you could set the button text to the action it’s performing, such as Crop or Rotate Image.

The final step in this code is to set the FileName property of the RotateFlipImage1 control equal to the FileName property of the e argument. As stated earlier, when a control is finished with its work (the user clicked the Finish button) it raises an event and passes an instance of the FileHandlingEventArgs class with it. This EventArgs class holds the filename of the finalized image. In the case of the SelectImage control, the filename is the virtual path to the image that has just been uploaded. This image will then be the source of the next control so it has an image to work with. By setting the FileName property of the RotateFlipImage control, that control knows with which image it should start working.

Although this example shows the code for the SelectImage1_ImageFinalized only, all four controls implement the same mechanism. The code-behind for Default.aspx has handlers for the ImageFinalized event, which run similar code to pass the filename from control to control and display the next step in the process.

In addition to the ImageFinalized event, all four user controls have the following properties and method in common:

365

Chapter 11

Method or Property Name

Type

Data Type

Purpose

 

 

 

 

FileName

Property

String

Determines the name and

 

 

 

location of the source file

 

 

 

that each control works with.

 

 

 

The source file of a control is

 

 

 

usually retrieved from the

 

 

 

previous control.

TempFileName

Property

String

A filename to store tempo-

 

 

 

rary versions of the images.

 

 

 

Because the SelectImage

 

 

 

control doesn’t need a

 

 

 

temporary image to work

 

 

 

with, it doesn’t have this

 

 

 

property.

FinishButtonText

Property

String

The text displayed on the

 

 

 

Finish button for each

 

 

 

control. To create a wizard-

 

 

 

style application, the text for

 

 

 

most buttons is set to Next.

btnFinish_Click

Method

n/a

Fires when the Finish button

 

 

 

gets clicked. Inside this

 

 

 

event handler, the final

 

 

 

image is updated and an

 

 

 

ImageFinalized event is

 

 

 

raised.

 

 

 

 

You see how these properties and the method operate when each of the four individual controls are discussed.

In addition to the ImageFinalized handlers, you’ll find two more methods in the code-behind of Default.aspx. The first is btnStart_Click, which fires when the user clicks the Start button on the homepage. The code for this method sets the ActiveViewIndex property of the MultiView to 1 to display the SelectImage control so a user can select and upload a file.

The second method is fired when the user clicks the btnSendEmail button. The code for this method sends an e-mail with the image as an embedded object in the message. You see how this works near the end of this chapter, after the four user controls have been discussed.

Uploading and Resizing Images

In the Greeting Card application, the user control SelectImage.ascx is the first step in the whole process, because it allows a user to select an image from the local hard drive and upload it to the web server. In addition to a number of Label controls that display various error messages and two placeholders that determine what part of the control is visible, it contains a few important controls that are listed in the following table:

366