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

ASP.NET 2.0 Instant Results

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

Wrox File Share

‘’’ The connection string property that pulls from the web.config ‘’’ </summary>

Public Shared ReadOnly Property ConnectionString() As String Get

Return ConfigurationManager.ConnectionStrings(“ConnectionString”).ConnectionString

End Get End Property ‘’’ <summary>

‘’’ The current theme of the website as defined in the web.config file ‘’’ </summary>

Public Shared ReadOnly Property CurrentTheme() As String Get

Return ConfigurationManager.AppSettings(“CurrentTheme”).ToString() End Get

End Property ‘’’ <summary>

‘’’ The HTML title value that each page displays, as defined here from the web.config file

‘’’ </summary>

Public Shared ReadOnly Property PageTitle() As String Get

Return ConfigurationManager.AppSettings(“PageTitle”).ToString() End Get

End Property ‘’’ <summary>

‘’’ The Local Folder File-Path for all files to be uploaded to on the server ‘’’ as defined here from the web.config file

‘’’ </summary>

Public Shared ReadOnly Property ShareLocalFolderPath() As String Get

Return ConfigurationManager.AppSettings(“ShareLocalFolderPath”).ToString()

End Get End Property ‘’’ <summary>

‘’’ The email subject line for all outgoing emails notifying users that they have been sent a file to download...

‘’’ </summary>

Public Shared ReadOnly Property EmailSubject() As String Get

Return ConfigurationManager.AppSettings(“EmailSubject”).ToString() End Get

End Property ‘’’ <summary>

‘’’ The configuration entry determining whether the email body is in HTML or plain text...

‘’’ </summary>

Public Shared ReadOnly Property EmailFormatSelected() As String Get

Return ConfigurationManager.AppSettings(“EmailFormatSelected”).ToString()

End Get End Property ‘’’ <summary>

57

Chapter 2

‘’’ The configuration entry determining the SMTP Server Name / Address ...

‘’’ </summary>

Public Shared ReadOnly Property SmtpServer() As String Get

Return ConfigurationManager.AppSettings(“SmtpServer”).ToString() End Get

End Property ‘’’ <summary>

‘’’ The configuration entry determining the httpDownloadPath...

‘’’ the default local value is : “http://localhost/FileShare/” which is set at the web.config

‘’’ </summary>

Public Shared ReadOnly Property httpDownloadPath() As String Get

Return ConfigurationManager.AppSettings(“httpDownloadPath”).ToString() End Get

End Property

End Class

As the Config class displays, the properties are marked as Public Shared ReadOnly, which allows them to be accessed from anywhere in the project by the config-dot notation. An example of this would be config.ConnectionString(). This would return the connection string from the Config class, without instantiating a Config class object first.

Resource.vb

The Resource class is used to retrieve and save the resource information being sent up to the web site. The class acts as a business layer and provides a level of abstraction between the requests for database records and the user interface.

By using #Region tags in the Resource.vb class file, the Visual Studio IDE allows the page to be grouped into organized sections. Sections that are commonly used to group the code in this way include Variables, Constructors, Methods, and Properties. This does not impact the .NET assemblies in any way, but is simply a great way to maintain organized logic. Figure 2-10 is a visual display of the regionalized code as it is displayed within the Visual Studio IDE.

Figure 2-10

One of the more important method calls of the resource is the SaveResource method. The code for this is as follows:

58

Wrox File Share

‘’’ <summary>

‘’’ Saves the <see cref=”Resource” /> by sending in the resource fields ‘’’ </summary>

‘’’ <param name=”filename”>The filename of the Resource.</param> ‘’’ <param name=”fromContactEmail”>The email of the sender </param> ‘’’ <param name=”message”>The message of the Resource.</param>

‘’’ <param name=”toContactEmail”>The email of the recipient</param>

‘’’ <param name=”ID”>The optional param: the id of the Resource.</param> Public Shared Function SaveResource(ByVal filename As String, ByVal

fromContactEmail As String, ByVal toContactEmail As String, ByVal message As String) As Integer

Return ResourceDB.SaveResource(filename, fromContactEmail, toContactEmail,

message)

End Function

This method provides the means by which to hand off a Resource class object to the data tier for processing. It accepts five parameters:

filename

fromContactEmail

message

toContactEmail

ID

These parameters represent the entire view of the resource class as it exists in the system.

resourceDB.vb

The resourceDB class is essentially the data layer for the application. It provides method calls to retrieve information from the database and insert or update data within the database as well. This class serves as the only file or object that will have access to the database files. In this way, you can isolate data-specific operations outside of the business logic layer. In so doing, you can see that it protects a developer from writing duplicate data access code and lends itself well to the function of maintaining organized and structured data access logic. This also supports the application being logically separated into tiers, or layers, with the deliberate feasibility of migrating and expanding the application onto separate servers at any point in time.

In line with the documented function call from the Resource class, the resourceDB class contains a Save method, as displayed here:

‘’’ <summary>

‘’’ Saves the <see cref=”Resource” /> to the database ‘’’ </summary>

‘’’ <param name=”filename”>The filename of the Resource.</param> ‘’’ <param name=”fromContactEmail”>The email of the sender</param> ‘’’ <param name=”message”>The message of the Resource.</param> ‘’’ <param name=”toContactEmail”>The email of recipient.</param>

‘’’ <param name=”ID”>The optional param: the id of the Resource.</param> Public Shared Function SaveResource(ByVal filename As String, ByVal

fromContactEmail As String, ByVal toContactEmail As String, ByVal message As String, Optional ByVal ID As Integer = Nothing) As Integer

59

Chapter 2

Using mConnection As New SqlConnection(Config.ConnectionString)

Dim mResourceID As Integer

‘Create a command object

Dim mCommand As SqlCommand = New

SqlCommand(“sprocResourceInsertUpdateItem”, mConnection)

‘set it to the type of ‘stored procedure’ mCommand.CommandType = CommandType.StoredProcedure

‘add in the parameters: the surveyID,

‘the question text, and the possible choices (A,B,C,or D) If ID > 0 Then

mCommand.Parameters.AddWithValue(“@id”, ID)

Else

mCommand.Parameters.AddWithValue(“@id”, DBNull.Value) End If

mCommand.Parameters.AddWithValue(“@filename”, filename) mCommand.Parameters.AddWithValue(“@fromContactEmail”, fromContactEmail) mCommand.Parameters.AddWithValue(“@toContactEmail”, toContactEmail) mCommand.Parameters.AddWithValue(“@message”, message)

‘open the connection and execute the stored procedure mConnection.Open()

mResourceID = mCommand.ExecuteScalar() mConnection.Close()

Return mResourceID

End Using

End Function

Another method of interest is the GetEmailBody() method, returning a string variable of the body of the e-mail template used for sending out e-mails to the recipient of the file share sender. The following is an excerpt of this method:

‘’’ <summary>

‘’’ Returns the HTML body of the email message to be sent out ‘’’ </summary>

‘’’ <param name=”msg”>The additional message provided by ‘’’ the user to be within the body of the email.</param> Public Shared Function GetEmailBody(ByVal msg As String, _ ByVal id As Integer, ByVal SenderEmail As String, _

ByVal RecipientEmail As String) As String Dim emailBody As String = “”

Try

Using mConnection As New SqlConnection(Config.ConnectionString)

Dim mLink As String

mLink = Config.httpDownloadPath & “Download.aspx?resourceID=”

Dim mCommand As SqlCommand = New _

SqlCommand(“sprocEmailSelectSingleItem”, mConnection)

60

Wrox File Share

mCommand.CommandType = CommandType.StoredProcedure mConnection.Open()

Using mDataReader As SqlDataReader = _ mCommand.ExecuteReader(CommandBehavior.CloseConnection) If mDataReader.Read() Then

‘get the email body template content from the email table emailBody = mDataReader.GetString( _

mDataReader.GetOrdinal(Config.EmailFormatSelected)) ‘replace the custom msg area with the message from the sender emailBody = emailBody.Replace(“[msg]”, msg)

emailBody = emailBody.Replace(“[link]”, mLink & id.ToString()) emailBody = emailBody.Replace(“[sender]”, SenderEmail) emailBody = emailBody.Replace(“[recipient]”, RecipientEmail)

End If mDataReader.Close()

End Using End Using

Catch ex As Exception

‘By calling the “Throw” statement, you are raising the error to ‘the global.asax file, which will use the default error handling ‘page to process/display the custom error to the user

Throw End Try

Return emailBody End Function

The preceding page logic performs the following steps:

1.Creates a new SqlCommand object, passing in the stored procedure name and the connection:

Using mConnection As New SqlConnection(Config.ConnectionString)

2.Creates a local variable used to concatenate the real hyperlink based on the configurationdriven design:

Dim mLink As String

mLink = Config.httpDownloadPath & “Download.aspx?resourceID=”

3.Sets the CommandType to be StoredProcedure, and provides the name of sprocEmailSelectSingleItem:

Dim mCommand As SqlCommand = New SqlCommand(“sprocEmailSelectSingleItem”, mConnection)

mCommand.CommandType = CommandType.StoredProcedure

4.Creates a new SqlDataReader:

Using mDataReader As SqlDataReader = _ mCommand.ExecuteReader(CommandBehavior.CloseConnection)

5.Calls the command’s Execute method. This executes the sprocEmailSelectSingleItem stored procedure and returns the result as a string value in a one-record row:

mCommand.ExecuteReader(CommandBehavior.CloseConnection)

61

Chapter 2

6.Assigns the ordinal value of data within the DataReader to a string variable, emailBody:

If mDataReader.Read() Then

‘get the email body template content from the email table emailBody = mDataReader.GetString( _

mDataReader.GetOrdinal(Config.EmailFormatSelected))

7.Replaces the values of the dynamic variables for the text message from the sender, the URL for the hyperlink used to download the file, the e-mail address of the sender, and the e-mail address of the recipient:

‘replace the custom msg area with the message from the sender emailBody = emailBody.Replace(“[msg]”, msg)

emailBody = emailBody.Replace(“[link]”, mLink & id.ToString()) emailBody = emailBody.Replace(“[sender]”, SenderEmail) emailBody = emailBody.Replace(“[recipient]”, RecipientEmail)

8.Returns the string value to the caller:

Return emailBody

This provides the desired abstracted functionality to retrieve the e-mail message body from the database, and return this text content to caller.

WebForms

The WebForms are standard ASPX pages that contain the client-side graphical user interface of the application. A few WebForms are of particular importance within the project, as noted in the following sections.

Default.aspx

The Default.aspx file is of course used as the first page that loads when the site is accessed. Within this page are the controls used to capture the essential file information for the uploading of the file into the system.

Several specific functions from this page should be mentioned. The first one is a common event with logic that is somewhat redundant throughout the application’s ASPX pages. This is the page initialize event, displayed here:

‘’’ <summary>

‘’’ this preinit event fires to initialize the page. It allows ‘’’ for the theme and title to be set for this page, which ‘’’ actually pulls from the web.config setting via the shared ‘’’ Config class’s exposed properties.

‘’’ </summary>

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit

Page.Theme = Config.CurrentTheme Page.Title = Config.PageTitle

End Sub

The Page.Theme is the theme property of the Page reference. By setting this theme property to the Config class’s exposed CurrentTheme value, you are assigning a theme at run time. This model of

62

Wrox File Share

assignment is ideal, because each page can dynamically utilize the theme that is controlled via the Web.config file, without requiring any other file changes.

The other area of special interest is the btnSend button’s Click event handler. This provides the uploading and saving of the information, and sends out an e-mail to the recipient.

Specifically, three processes provide the sending or capturing of the file. They are as follows:

Text data inserted into the database about the file.

The actual file uploaded to the storage folder on the server.

An e-mail sent to the recipient with notification of the file being ready to download.

The code for the Click event is as follows:

Protected Sub btnSend_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnSend.Click

If FileUpload1.FileName <> “” Then ‘upload the file to the server...

FileUpload1.SaveAs(Config.ShareLocalFolderPath _ + FileUpload1.FileName)

‘save the info to the database...

Dim ResourceID As Integer = Resource.SaveResource( _ FileUpload1.FileName, txtSenderEmail.Text, _ txtRecipientEmail.Text, txtMessage.Text)

‘get the body of the email message...

Dim emailBody As String = Resource.GetEmailBody( _ txtMessage.Text, ResourceID, txtSenderEmail.Text, _ txtRecipientEmail.Text)

‘send an email to the recipient...

Utilities.SendEmail(txtRecipientEmail.Text, _ txtSenderEmail.Text, Config.EmailSubject, emailBody)

Server.Transfer(“UploadComplete.aspx”, True) End If

End Sub

This event performs the most essential portion of logic within the application by far, and is the crux of the programming effort to host a file share application of this kind. The event is so critical because it performs the specific upload, save, and e-mail functionality that the application is known for. If you want to add additional features to the application in a big way, you will probably want to start here and work your way into the deeper layers of the application.

Login.aspx

The Login page contains a Login control and a PasswordRecovery control. The Login page is located at the root of the web site and does not use a master page. The Login controls contain HTML markup (shown in the following code) that defines the specific values for the destination page and text values of the controls.

<fieldset style=”height: 128px; width: 270px;”> <asp:Login ID=”Login1” runat=”server” DestinationPageUrl=

“~/Management/ManageEmail.aspx”>

63

Chapter 2

</asp:Login>

</fieldset> <br />

<br />

<fieldset style=”height: 118px; width: 270px;”> <asp:PasswordRecovery ID=”PasswordRecovery1” runat=”server”> </asp:PasswordRecovery>

</fieldset>

The preceding HTML markup contains the control definitions for the Login and PasswordRecovery controls and their properties.

Download.aspx

The Download.aspx WebForm is used to provide access to the files stored within the web site, without forcing the user to view a web page filled with advertisements.

The Page_Load event of the page is as follows:

‘’’ <summary>

‘’’ this load event fires to process the display of ‘’’ the download dialogue for the file

‘’’ </summary>

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

DisplayDownloadDialog(Config.ShareLocalFolderPath & _ Resource.GetResourceFileName(Request.QueryString(“resourceID”)))

End Sub

This event calls the DisplayDownloadDialog function, passing in the Config.ShareLocalFolder Path and a querystring variable, resourceID. The Config.ShareLocalFolderPath is the property exposed by the Config class that refers to the local file share on the web site. This allows for a direct output of the file object programmatically, because it is a local pointer to the file on the server. The resourceID querystring variable is the ID of the resource record the page will be referencing as it attempts to return a downloadable file to the client. Each file on the Wrox File Share has an ID number, known as the resourceID. It is this number that allows you to query the database and extract the name of the file to be downloaded.

The following is the DisplayDownloadDialog function from the download.aspx.cs WebForm codebehind page:

Sub DisplayDownloadDialog(ByVal PathVirtual As String) Dim strPhysicalPath As String

Dim objFileInfo As System.IO.FileInfo Try

‘strPhysicalPath = Server.MapPath(PathVirtual) strPhysicalPath = PathVirtual

‘exit if file does not exist

If Not System.IO.File.Exists(strPhysicalPath) Then Exit Sub

End If

objFileInfo = New System.IO.FileInfo(strPhysicalPath) Response.Clear()

64

Wrox File Share

‘Add Headers to enable dialog display Response.AddHeader(“Content-Disposition”, _

“attachment; filename=” & objFileInfo.Name) Response.AddHeader(“Content-Length”, objFileInfo.Length.ToString()) Response.ContentType = “application/octet-stream” Response.WriteFile(objFileInfo.FullName)

Catch ex As Exception

‘By calling the “Throw” statement, you are raising the error to ‘the global.asax file, which will use the default error handling ‘page to process/display the custom error to the user

Throw Finally

Response.End() End Try

End Sub

This excerpt provides a file in the form of an Open or Save dialog box, as noted in the previous section, “Using the Wrox File Share.”

Instead of a typical web page displaying advertisements, the Wrox File Share provides a directly streamed file to HTTP caller from the click of a hyperlink. The response of the page is cleared, headers are added to it, and the file object is written to it before it is returned to the caller. This allows the page to return a file, a fast and clean approach to downloading the file.

The Download page is extensible in that the application could be easily modified so that another page would be loaded first, with a link to the download.aspx page, passing in a resourceID querystring variable. As such, the file could be re-downloaded or downloaded in a safer fashion, using a clickable button or button-link to initiate the request. This is more commonly used across the board, because many download pages are riddled with advertisements and problematic page elements that seem to be the cause for failed download attempts.

User Controls

Some specific user controls in the site assist with the navigation and content display for multiple pages. Because web user controls promote a practice of creating and using reusable code, they were made to be applicable within multiple pages of the site, depending on the nature of the controls.

header.ascx

The header user control is used to provide the top area of each page with meaningful content. If anything needs to reside at or near the top of a web page, you would want to add it to the header control so it will be visible through all of the pages.

The following code represents entire header.ascx source:

<%@ Control Language=”VB” AutoEventWireup=”false” CodeFile=”header.ascx.vb” Inherits=”Controls_header” %>

<div style=”text-align: center”> <table><tr>

65

Chapter 2

<td><img src=”../Images/headerlogo.gif” /></td> <td><h1><% Response.Write(Page.Title) %></h1> </td>

</tr></table>

</div>

Notice that the <%Response.Write(Page.Title)%> tags are used to write back to the response stream a title of the web site on the top of each page, which originated from the Web.config file.

footer.ascx

The footer user control is used as the bottom section of the site, for each page that uses the master page. That is, the footer control, among others, is a referenced control within the master page. In this way, it is propagated to all pages in the same exact manner.

The content of the footer control is displayed here:

<%@ Control Language=”VB” AutoEventWireup=”false” CodeFile=”footer.ascx.vb” Inherits=”Controls_footer” %>

<a href=”http://wrox.com” target=”_blank”>© 2005 Wrox Press</a>   

<asp:LoginStatus ID=”LoginStatus1” runat=”server” LogoutAction=”RedirectToLoginPage”

LogoutPageUrl=”~/Login.aspx” />

This excerpt includes a reference to a LoginStatus control, brand new in the ASP.NET 2.0 controlset. The new control displays a changing link-button for providing log-in and log-out functionality. When users are logged in to the site, the LoginStatus control displays a Logout link-button. Clicking the Logout link-button logs users out of the site, and directs them to the Login page. When users are logged out of the site, the LoginStatus control displays a Login link-button. Clicking the Login link-button directs them to the Login page, where they are able to log in.

navigation.ascx

The navigation user control is used to provide the reusable menu on each page of the site. The Menu control itself is a brand new ASP.NET 2.0 control that binds to a SiteMapDataSource control, also new in version 2.0 of the .NET Framework. The SiteMapDataSource control is used to bind to an XML file, wherein the site files are listed as entries in the XML file.

The following excerpt is the HTML markup of the navigation control:

<%@ Control Language=”VB” AutoEventWireup=”false” CodeFile=”navigation.ascx.vb” Inherits=”Controls_navigation” %>

<asp:Menu ID=”Menu1” runat=”server” DataSourceID=”SiteMapDataSource1” Orientation=”Horizontal”

StaticDisplayLevels=”2”></asp:Menu>

<asp:SiteMapDataSource ID=”SiteMapDataSource1” runat=”server” />

The XML file of the SiteMapDataSource control is displayed here:

<?xml version=”1.0” encoding=”utf-8” ?>

<siteMap xmlns=”http://schemas.microsoft.com/AspNet/SiteMap-File-1.0” > <siteMapNode url=”ContentFiles/default.aspx” title=”Home”>

66