Using ASP.NET s Built-In Classes

function OpenWin(url, w, h) { if(!w) w = 400; if(!h) h = 300; window.open(url, "_new", "width=" + w + ",height=" + h + ",menubar=no,toobar=no,scrollbars=yes", true); } function Print() { window.focus(); if(window.print) { window.print(); window.setTimeout('window.close();',5000); } }
Team-Fly    

Special Edition Using Microsoft® Visual Basic® .NET
By Brian Siler, Jeff Spotts
Table of Contents
Chapter 17.  Using Active Server Pages.NET


Using ASP.NET's Built-In Classes

Starting with ASP.NET, the full Visual Basic language is available to Active Server Page developers, so the language concepts in the rest of this book also apply to ASP.NET development. In addition, Microsoft has provided several Web-centric classes that are exposed as objects in any ASP.NET page. You have already seen an example use of one such object, the Response object, used to manage the server's response to a Web request. Many of these objects will be familiar to ASP developers, but with new features or subtle changes. In the remainder of this chapter, we'll look at some important objects provided by the ASP.NET architecture and how they can be used in your ASP.NET applications.

Using the Session Object

A session with an ASP.NET application can be compared to a session with a psychiatrist. It starts when you enter the psychiatrist's office, ends when you leave, and is over after a fixed period of time. During your visit, you might discuss a variety of topics; analogous to the various Web pages you visit on a Web site. One popular feature of Active Server Pages that is still available in ASP.NET is session variables. Session variables are user-specific and have a scope of the current ASP.NET session. They are stored on the Web server and are accessible from server-side code. To set a session variable, you simply give it a name and assign a value:

 Session("UserId") = "bsiler"  Session("CurrentPurchases") = 19.95  Session("ShippingMethod")="Standard"  Session.Add("YearsWarranty",5) 

The previous lines of code show how to set session variables. The last line uses the Add method, which is new to ASP.NET. After you have created a session variable, the Web server will maintain its value until the user's session ends. Some of the ways in which a session can end are as follows:

  • A user closes the browser.

  • The session times out after the number of minutes specified in the Session.Timeout property. (As long as the user continues to interact with the server, the session will remain active.)

  • Your code calls the Session.Abandon method to purposely terminate the session.

Note

There is nothing preventing a user from bouncing all over the Web; don't count on being able to precisely know who is logged in and when.


After a session ends, the contents of any session variables are destroyed. They are best suited for temporary information that you do not want to store on the client.

Managing Security with Session Variables

One frequent use of session variables is to control security across multiple pages. For example, suppose you have an intranet site with a login page. The login page could set a session variable containing the name of the current user, which would then be available to other pages. Suppose you have the following three pages on your intranet site:

  • usermenu.aspx Displays a list of links to other pages, based on the current user name.

  • hrsalary.aspx Displays payroll reports.

  • cafemenu.aspx Displays the offerings of the company lunchroom.

On our fictional intranet, the first page a user sees after signing in is usermenu.aspx, which would read a database and display a list of links to the other two pages, depending on whether the user had access. For example, everyone would probably be able to view the lunchroom offerings, but only selected users would see the menu option for payroll reports. It is easy enough to read a database and generate a page of links customized for a given user ID, but how do you prevent users from simply typing in the address of the page they want, bypassing the menu page entirely? One solution is to include a security check at the top of every page:

 <%  If Not CheckValidUser("hr",Session("UserID")) Then     Response.Write("Access denied!")     Response.End  End If  %> 

The previous lines of code pass the name of the application (hr) and the value of the UserID session variable to a custom function, CheckValidUser. If the CheckValidUser function returns False, any code or HTML beneath the security check is not processed. (A real-world application would probably redirect the user to a page requesting he sign in again, in case the session timed out.)

Creating a Custom Security Database

With all the talk about security and hackers, it is easy to get confused about the different types of security involved in running a Web site. Security can exist at the network level to prevent people from spying or altering the data being transmitted over a network connection. This type of security is usually implemented using fire-walls or a secure sockets protocol, and by itself could be the topic of a whole book. (By the way, when you see https in a URL, you are using secure sockets.) The security discussion in this chapter is more closely related to application security, which falls closer to the realm of application design than network security. Security at the application level is concerned with making sure the application is aware of the end user's identity so it can display the appropriate information. For a recent project, my workgroup was able to design a SQL database and associated Visual Basic classes that we use to administer security company-wide across all our Web applications. In designing such a database, it is important to make it as flexible as possible. At a minimum you will need tables to represent application tasks, users, and user permissions for those tasks. In addition, you may want to consider the following when designing a security model:

  • What information will you need to store about the user? For example, will users at the corporate office need to see a different home page and therefore need to be designated as special user types in the database?

  • Does your security model need to assign access for individual users, groups of users, or both?

  • Will your security model be date sensitive? If so, you will need start and end date fields on the user and/or permission records.

  • How are the units of your company organized? This is a very important question, because it will determine the granularity of your security model. For example, suppose you manage multiple restaurants. Each restaurant will probably have some internal company ID number. In this case, you will probably want to include this ID number in your security database. This will permit you to assign each application task to specific users for specific restaurants.

In addition to designing a flexible security database, you will need to apply the same types of considerations when creating classes to access that database. By using classes rather than having the applications directly access the database; you can keep the security logic separated from the application logic. These classes should be generic to apply to multiple applications, but still support a useful level of security. For example, you may need to write some ASP code that displays a menu of reports. Continuing with the restaurant example, you should be able to ask a security business object a question like "return a list of restaurant ID's for task 123 for user jsmith" that the application could then process appropriately.

Maintaining a Session Across Servers

Session variables are both useful and easy to use, but they can be a bad habit. If you have been to any ASP seminars in the past year, you have probably heard Microsoft preaching against their use. There are two main reasons for this: insufficient use of server resources and incompatibility with server farms. Each session variable takes up some amount of memory on the server. In an environment where the number of users may vary widely, this problem will compound itself the more session variables per user you have defined. Because a lot of sessions are terminated by timeouts, your Web site may not be very scalable due to wasted memory. Of course, it is not a big deal to store a one object in a session variable, such as a userid. Given a userid, you can probably easily retrieve anything else your page needs to function with a VB method call or database lookup.

However, if your Web site uses multiple servers, you may not even have the option of using session variables. A server farm is a group of servers that acts as a single Web site for load balancing purposes. With each request for a Web page, you may be directed to a different physical server. In this scenario, traditional session variables stored on the server just do not work. To get around this problem, you need to use another method such as a database. Hidden form fields and cookies, which we will explore in a later section, can be used to store the database key on the user's machine. Although the intricacies of a Web farm are beyond the scope of this book, it is worth mentioning that the latest version of ASP does take server farms into consideration. ASP.NET allows you to specify a SQL database in which to store session information. For more information, see the help file topic "Session State in ASP.NET."

Controlling Output with the Response Object

Every time the client requests a page from the Web server, a response is sent. The Response object, which is an instance of the HttpResponse class, is used to manage the server response. We have already introduced to you one of its most common uses, sending the contents of a variable or other HTML codes back to the client with the Write method.

Table 17.2 lists some of the most useful properties and methods of the Response object.

Table 17.2. Frequently Used Members of the Response Object

Member Name

Description

Write

Sends text to the browser.

End

Ends the current response.

Redirect

Sends the browser to another page.

IsClientConnected

Checks for user connection.

Cookies

Provides access to client cookies.

Cache

Controls caching of page content.

Redirecting the User to Another Page

We have already seen examples of the Response.Write and Response.End methods. Response.Redirect tells the browser to request another page, as in the following example:

 <%  If Not CheckValidUser("hr",Session("UserID")) Then     Response.Redirect("/security/login.htm")  End If  %> 

The previous code sample is a security example from the last section, rewritten to send the user back to the login page. Note that Response.Redirect can only be used if no other HTML has been sent back to the browser. If the file contained any HTML or a Response.Write prior to the Redirect statement, an error would occur.

Note

As an alternative to Response.Redirect, newer versions of IIS offer Server.Transfer. Response.Redirect involves an extra round trip to the client and back (the server tells the browser to request a new page) whereas the Server.Transfer function substitutes one page for another at the server level.


Terminating a Long Response

The IsClientConnected property provides the capability to check whether a user is connected to the Response being generated. A typical request-response scenario takes only a few seconds, but for a lengthy response you might want to stop responding if the user has terminated the session:

 <%  Call LongProcessNumberOne()  If Not Response.IsClientConnected Then     Response.End  End If  Call LongProcessNumberTwo()  Response.Write("Done!")  %> 

In the previous example, we assume the function calls each take a significant amount of time. By checking the IsClientConnected property, we can avoid extraneous processing if the user has given up waiting.

Sending Cookies to the Client

Cookies are little pieces of data stored on the client. With each Web request the cookies are sent back to the server and accessible from ASP.NET code, which allows you to perform tasks such as site personalization. (IIS actually uses cookies to help manage sessions.) For example, the following lines of code send a Zipcode cookie back to the user:

 Dim ckZip As New HttpCookie("Zipcode")  ckZip.Value = "38138"  ckZip.Expires = DateTime.Now.AddDays(30)  Response.Cookies.Add(ckZip) 

When the user accesses the site again, the Zipcode cookie will be sent to the server, allowing it to display the weather or other ZIP Code-related information automatically. The Expires property of the cookie instructs the browser to throw it away after 30 days.

Note

If you are curious how and where cookies are stored, look in the Temporary Internet Files folder. To view these files from Internet Explorer, choose Internet Options from the Tools menu and click View Files. Drag one of the cookie files (begins with the word cookie) to the desktop and then open it in a text editor.


In addition to storing scalar values, a single cookie object can store multiple related values, as in the following example:

 Dim ckFavoriteStocks As New HttpCookie("Stocks")  ckFavoriteStocks.Values.Add("MSFT", "Microsoft")  ckFavoriteStocks.Values.Add("HLT", "Hilton")  ckFavoriteStocks.Values.Add("FDX", "FedEx")  Response.Cookies.Add(ckFavoriteStocks)  Dim MyCookie As New HttpCookie("LastVisit")  MyCookie.Value = CStr(DateTime.Now())  Response.Cookies.Add(MyCookie) 

As you can see, cookies are good for small bits of machine or session-specific information. For the problem we mentioned earlier (managing session state), one solution is to store a cookie that acts as a database key. However, because cookies are stored as plain text, I would recommend the following precautions when using cookies to keep track of a user's identity:

  • Use a random number (that is a GUID) rather than any actual key value from the database.

  • If your Web site has a list of users, do not display their random number in URLs.

Without taking the previous precautions, a user could edit his cookie file and impersonate another user.

Controlling Response Caching

Another useful property of the Response object is the ability to set a cache policy. Your browser will store all the HTML and images associated with a response in its temporary directory for a certain length of time for speed purposes. By manipulating the Cache property of the Response object, you can send directives to the browser informing it of how long the page should live in the cache:

 'SETS CACHE TIME TO 25 MINUTES  Dim ts As New TimeSpan(0, 25, 0)  Response.Cache.SetMaxAge(ts) 

The previous lines of code set the maximum age of the current response to 25 minutes. For certain types of applications, such as an up-to-the-minute Webcam, you may want to set the cache expiration time to a very low value, or even use the Response.Cache.SetNoStore method to direct the browser to always retrieve the page from the server.

Retrieving Data with the Request Object

The Request object allows ASP.NET code to access information about an incoming Web page request. The most common use of the object is to retrieve data from HTML form submissions or cookies for use in VB code. However, the Request object also provides a number of properties that you can use to obtain information about the files and directories associated with an incoming request.

Retrieving QueryString Data

As you may have noticed, the URL of a Web page can contain parameters following the address. Consider the following example URL:

 http://bshome/getreport.aspx?title=Payroll&dept=23&format=PDF 

The previous address refers to the getreport.aspx page, and passes three parameters: title, dept, and format. Values for parameters can be accessed by name using the Request.QueryString collection. The following lines of code retrieve the values of parameters from the example URL and store them in variables:

 Dim strTitle As String  Dim intDeptNumber As Integer  Dim strFormat AS String  strtitle = Request.QueryString("title")  intDeptNumber = Request.QueryString("dept")  strFormat = Request.QueryString("format") 

As you will see in an upcoming exercise, you can use the Response.Write statement to dynamically create a hyperlink containing URL parameters.

Note

When using parameters in a URL, separate the address and first parameter with a question mark (? ) and each subsequent parameter with an ampersand (&).


Be careful what information you expose to the user in the URL. Security is worthless if it can be overridden by a change in a URL. For example, I have seen poorly designed Web sites that store a SQL statement in the URL, giving the user free reign over the database!

Retrieving Data from HTML Forms

In order to transfer data to the server from the client, you can set up a form in HTML. Forms are enclosed by the <FORM> tag and contain <INPUT> fields. When a form is submitted to the Web server, the values of the fields are available via the Request.Form collection. To see how this might work in practice, create a new file in the ASPTest directory called default.htm and enter the code from Listing 17.3.

Listing 17.3 ASPTEST.ZIP Submitting Form Variables
 <HTML>  <BODY>  <H1>Security Check</H1>  <HR>  <FORM ACTION="checkuser.aspx" METHOD="POST">  User ID: <INPUT TYPE="TEXT" NAME="txtUserID"><BR>  Password: <INPUT TYPE="PASSWORD" NAME="txtPassword"><BR>  <INPUT TYPE="SUBMIT" VALUE="LOGIN">  </FORM>  </BODY>  </HTML> 

Listing 17.3 contains a simple HTML form with two form fields and a Submit button. The form appears as shown in Figure 17.5.

Figure 17.5. Form elements using the POST method are not visible in the URL, as with the QueryString.

graphics/17fig05.gif

To process the form, create a file in the ASPTest directory called checkuser.aspx. Enter the following lines in the new file:

 <%  If Request.Form("txtPassword").ToLower = "password" Then     Response.Write ("Congratulations, " & Request.Form("txtUserId"))     Response.Write ("<BR>You entered the right password!")  Else     Response.Write ("Sorry, " & Request.Form("txtUserId"))     Response.Write ("<BR>Access denied!")  End If  %> 

To test the sample page, open your browser to the address http://servername/ASPTest. You should see the page shown in Figure 17.5. Enter your user name and see what happens when you enter password for the password and when you enter something else.

Caution

Unencrypted HTML form data sent back and forth across a network can be "sniffed" by someone on the same network who is analyzing data packets. If you are concerned about exposing passwords, you may want to investigate a secure connection for the login form using the https protocol.


Forms and URL parameters are a common way to pass simple values from page to page without using session variables, as long as you don't mind that value being seen by the client. One type of form field that is very useful in this regard is the HIDDEN type, which works like an invisible text box. However, the user can read even the data in a hidden form field if he chooses the View Source option.

Determining Cookie Values

As we saw earlier, the Response object contains methods for sending cookies to the client. Similarly, the Request object contains methods for retrieving those values. One way to do this is to use the same collection-based approach:

 Dim strZipCode As String  If Not IsNothing(Request.Cookies("ZipCode")) then     strZipCode = Request.Cookies("ZipCode").Value  End If 

Note that unlike the other collections in the Request object, we have to explicitly specify the Value property to specify the value stored in the cookie object, rather than the cookie object itself. You can also declare an HttpCookie object, which may be an easier method of accessing multi-value cookies. The following code reads the stock cookie example from the last section:

 Dim ckStocks AS HttpCookie  Dim i As Integer  Dim strSymbols() AS String  If Not IsNothing(Request.Cookies("Stocks")) then     ckStocks = Request.Cookies("Stocks")     'Get all the key names into an array     strSymbols=ckStocks.Values.AllKeys     'Use the key name to retrieve the description     For i = LBound(strSymbols) To UBound(strSymbols)             Response.Write ("Symbol=" & strSymbols(i) & "<BR>")             Response.Write ("Description=" & _               ckStocks.Values(strSymbols(i)) & "<BR>")     Next  End If 

Reading a multi-value cookie is a little more complicated. Of course, in this example the stock data is so simple you could easily store it all in a single comma-delimited string. It is left as an exercise to the reader to judge which method is easier.

Retrieving Values by Name

Throughout this section we have identified several collections of values stored in the Response object. One new collection to ASP.NET is the Params collection, which acts as a combination of cookies, QueryString values, server variables, and form fields. The following code shows how to access some of the values from previous examples using the Params collection:

 strZipCode = Request.Params("ZipCode")  strPassword = Request.Params("txtPassword")  intDeptNumber = Request.Params("dept") 

For accessing simple values by name, the preceding lines of code work just as well as any other method. However, from the point of view of good programming practice, you should know where your values are stored.

Understanding the Server and Application Objects

The Server object allows you to control perform actions on the Web server, such as creating objects and executing code. In previous versions of ASP, the Server object was the only means of accessing your external business objects (late bound), using the CreateObject method. However, in the .NET world you have access to all the power of VB, including early bound objects and importing namespaces as discussed earlier. The CreateObject method is still available for compatibility with existing COM objects:

 <%  Dim cn As Object  cn = Server.CreateObject("MyComObj.MyComClass")  %> 

Hopefully, you will need to use the CreateObject method sparingly if ever. Note that for some COM objects, you may need to add the directive <%@ Page aspcompat=true %> at the top of your page. For more information on compatibility with COM, see the help files.

As mentioned earlier, the Server object also provides a way to substitute one page for another at the server level. The Server.Transfer method accepts the new page address as a parameter:

 Server.Transfer("default.aspx") 

The preceding line of code transfers control of the current response to the default.aspx page. In some cases it may be more desirable than the Response.Redirect method because it avoids an extra round trip to the client. Another advantage is it can be called even after writing HTML back to the client. However, keep in mind when using Server.Transfer the URL the user sees for the page may not represent the actual page displayed.

Note

Server.Transfer cannot be used with .htm files, only .aspx files.


Another interesting object available in ASP.NET is the Application object. The Application object allows you to set variables that are available to all users of an application:

 Application("CompanyStockPrice") = 64 

These variables work similarly to session variables, and the value is preserved as long as the application is active (there is at least one active session).


    Team-Fly    
    Top
     



    Special Edition Using Visual Basic. NET
    Special Edition Using Visual Basic.NET
    ISBN: 078972572X
    EAN: 2147483647
    Year: 2001
    Pages: 198

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net