Expert Answer Center > Experts On Demand
EMAIL THIS
Experts on Demand
  EXPERTS ON DEMAND HOME     POSE A QUESTION     VIEW ANSWERS     BROWSE BY TOPIC        RSS FEEDS  
FEATURED TOPIC: ASP, ASP.NET, ADO and ADO.NET
VIEW FEATURED TOPIC PAGE
ASP, ASP.NET, ADO and ADO.NET
Blog Host:
Andrew Young - Senior Application Developer, Wheelock, Inc.
READ ENTIRE BIO
Key points of ASP.NET, part 3
23 SEP 2005 23:48 EDT (03:48, GMT)
Well, this is my swan song. There is much that I have not had a chance to cover, and that is discouraging. In this, my last blog entry on the Expert Answer Center, I want to get into the ADO.NET discussion, as that was part of the topic subject. I had hoped to at least touch on XML, but, unfortunately, there was not enough time. Looking at the previous blog entry, I think perhaps that I have gone as far as time will permit on the namespaces. We covered most of the basic concepts involved with them and looked at some simple examples that demonstrated how to extend classes within the .NET framework, and this led to a brief discussion on how to build new ones.

In summation, I would add what is already apparent: The .NET framework is an example of a truly object-oriented infrastructure. Each Web form that you add to your project is linked to an automatically generated code-behind page. The code-behind page contains a namespace reference to your project and defines the class that is your Web form. This class can extend any class or classes within the .NET framework, provided that you add a reference to the DLL file that contains the components that you are extending. For anyone with a CS background, this is nothing new…it is, literally, an example of all of those concepts we learned in our CS college classes way back when, only now they are being applied in a working GUI IDE that produces much more extensive and eye-pleasing results. I remember thinking about how all those classes were being wasted on linked lists and seemingly useless dissertations on binary tree recursion. But the familiarity I innately experience when looking at the design of this IDE makes me realize that the whole time a discipline in a line of thought was being established. Although many of the classes in the .NET framework are unfamiliar (there are so many, it would take years to know them all, if that is really even necessary), it is the concept of the hierarchy and how inheritance works that is the key.

ADO.NET
The improvements to the ADO technology with the introduction of ADO.NET are drastic. This was not an upgrade; actually, it was an overhaul. Yet, with all of the new features and functionality, existing ADO code and objects, like recordsets, will still work. The only thing that I have found not to work, as previously mentioned, is the CDONTS code.

The ADO.NET architecture consists primarily of DataSets, DataReaders, DataAdapters and DataViews. They are presented through the browser via list-bound controls such as data grids, list boxes or drop-down lists. You have many options as to how you build these interfaces when working with Visual Studio.NET.

There are several types of data adapters. Out of the box you have the availability of a SQL data adapter, OLEDb data adapter, ODBC data adapter and an Oracle data adapter. I have not done it, but I don't see any reason why you cannot create your own data adapters as well. Remember, everything in the .NET environment is based upon the namespace that contains the classes or the components of the DLL file that we are referencing. If someone has created a Lotus Notes data adapter, for example, simply copy that DLL file locally and add it as a reference to your project to gain access to its classes.

The names of the data adapters are self-explanatory. You can use the OLE or the ODBC data adapters to connect to miscellaneous data sources such as dBase, Access, FoxPro, etc. Let's continue in this example by revisiting our CD project from the ADO discussion.

To use a data adapter, you must supply it with an accompanying data connection and generate a data set. You will then fill the data adapter with data from the data set and bind it to a list-bound or Web-bound control. It is very easy to do this by dragging and dropping the objects onto your Web form. This will invoke wizards that will guide you through the configuration process and automatically create all of your code within the code-behind. Let's look at two examples -- one is an ODBC application done in VB, the other an OLE application done in C#:

First, let's look at the ODBC approach. Begin by creating a data connection. You can either code it manually, create if from the server explorer or drag and drop an ODBCConnection object onto the Web form. I have found the easiest way to create the connection in the server explorer, which will make it an available source when configuring your data adapter. To do this, open the server explorer and right click on data connections, then select "Add Connection." Choose "Microsoft OLE DB Provider for ODBC Drivers" as the provider, then choose to build your connection string via the button in the connection area. This will invoke a wizard that creates a DSN entry within your application. This will look very familiar to anyone who worked with early versions of ASP for Access connectivity. Upon completion, you will return to the Web form, and the connection will be visible as a data connection in your server explorer. Drag and drop the ODBC adapter object onto the Web form and complete the wizard, pointing it at this connection. The wizard will even allow you to create queries and insertion and deletion statements into your adapted object. When finished, right click the adapter and select "Generate Dataset." You should be able to accept the defaults and click OK. Next, drag a data grid onto the Web form. Right click the object and select "Property Builder." This will generate a full configuration panel for your grid. Point the data source to the data set you just created, and point the data member to the table in that data set. The remaining tabs of the property builder will allow you to easily configure the desired look and feel of the object. You can even set the paging size of the grid, which will allow page scrolling of the data contents.

Upon completion of these steps, it's time to add the three lines of code to make the application work. It would appear that it would work as is. At this point, you will see that your data grid column headers have taken on the names of your fields from the Access database. But we have not yet actually bound the data to the data grid server control. In the code-behind page, you will notice that lots of things have been added. In your page load event, add something like this (depending on the names of your objects, you might need slight adjustments):

OdbcDataAdapter1.Fill(Me.DataSet11)
DataGrid1.DataBind()
DataGrid1.Visible = True
Now, view the page in a browser. With less than half of the effort we put into achieving the same thing in ASP, we now have the same dynamic table, but also with superior display features.

The OLE approach is almost exactly the same. However, when you create your connection, use "Microsoft.Jet.OLEDB.4.0" as your provider. Configure the adapter, generate a dataset, then add the same code, replacing it with the OLE objects, to bind the data to the Web control:

oleDbDataAdapter1.Fill(this.dataSet11);
DataGrid1.DataBind(); 
Of course, you might consider also wrapping that within a postback test, but that depends upon the context of your application. Like all other objects within the .NET framework, you can code a simple application like this to "jump through hoops" for you. Just spend some time looking at the classes within the namespace hierarchies, and practice deploying them in test applications. For example, you can add buttons to this page to perform various processes on the same data grid, such as changing the data that is bound to that grid or even allowing users to define their own queries and creating dynamic connection objects and adapters, along with dynamic server controls to display them.

Converting existing HTML pages to Web forms
A very quick and painless way to create some ASP.NET pages is to work with some of your existing HTML pages. It is a simple, built-in process that will help get you started. To do this, follow these steps:

  • Create a new ASP.NET Web application in whatever language you prefer. Name it accordingly.

  • From the Project menu, select "Add Existing Item." Change the "files of type" selection to "All Files(*.*)." Browse to the HTML file you want to convert, and select it.

  • You will see the file that you selected located now within your solution explorer. Right click on it and select "Rename." You will be prompted to create a class for the new page. Select "Yes."

  • Double click on the page in design view. This will open the new code-behind page that contains the class that you just created. Switch back to the UI page, and toggle to the HTML view. You will notice that a new @Page directive has been added to the top of the file. Your conversion is a success.
Again, there is so much more to cover. I barely scratched the surface, especially with the ADO.NET discussion. Everything mentioned is also XML-compatible…and that is yet another discussion we did not get to, unfortunately. I had hoped to provide an example of sending text messages through XML via ASP.NET, but the host provider charges a fee and I could not gain timely permission to use their optional demo logins for the amount of potential traffic that I might have generated. The site is loaded with cool XML Web service features that you might want to check out, and it is located here.

Thanks to all of you who submitted questions and read this blog…for those of you who have submitted questions that I have yet to answer, keep checking back, because I will. Good luck to everyone in his or her development hopes and aspirations.
Posted by Andrew Young Key points of ASP.NET, part 2
22 SEP 2005 23:19 EDT (03:19, GMT)
There is so much more to cover in so little time. So let's get into it. Let's continue by looking at the postback functionality. Postback refers to an inherent ASP.NET form design. Forms post information back to the ASP.NET page for processing, at the server. Without modification, only the click event of a button control will invoke a form to be posted back to the server. All controls, however, have a built-in property that will force a postback; it is called the "AutoPostBack" property. Adding AutoPostBack="True" to any control will force it to postback to the server immediately as events for that control occur.

You can also manipulate postback processing using the Page.IsPostBack property within a conditional statement. Let's look at a simple example. I rewrote yesterday's project using C# to keep the discussion well-rounded:

private void Page_Load(object sender, System.EventArgs e)
  {
   if (!IsPostBack)
   {
   //this code only executes on initial page load
    sPage = (WebForm1) Context.Handler;
    if (sPage.Property1 == "test")
    {
     TextBox1.Text = "You are testing"; 
} 
    Else
{
     TextBox2.Text = "You are not testing";
    }
    
   }
   //all code here will execute upon each request
  }
We only need the code to execute once in this case, that is, immediately when the page loads for the first time. Any code placed outside of our postback test condition will execute upon every request. If we were only using one Web form in this demo and were posting it back to itself, we would not want to prevent a postback, since that would cause our code not to execute, clicking our button would do nothing. You can also leverage the System.Web.UI.Ipostback event handler interface to raise event responses on the server to postback calls from the client. This can be a bit tricky, and I would recommend thoroughly examining what you might gain from it that you could not achieve otherwise. For further documentation, look at the "Capturing Postback Events" entry of the .NET Framework Developers Guide.

Postback improves performance in that it enables us to eliminate redundant interactions between the client and the server. Ignoring that aspect of your project will predict its overall performance efficiency.

Demystifying the namespace
Namespaces logically group the classes that comprise the .NET framework. They can be used by any .NET-based language and are usable in your application by types; that is, each namespace contains types that you can use. To use the classes in a namespace, you can either type each full namespace hierarchy or declare it with a statement at the beginning of your application. A new C# ASP.NET Web form provides several examples of the declarative statement for a namespace:

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Web.UI.WebControls; etc…
With this approach, we can now declare objects implicitly and access the methods within that namespace directly by the method name. Our textbox is an example:
TextBox1 = new TextBox();
TextBox1.Text = "You are testing";
If we had not declared the System.Web.UI.WebControls namepace, we would have to rewrite this code with an explicit declaration:
System.Web.UI.WebControls.TextBox = new System.Web.UI.WebControls.TextBox();
TextBox1.Text = "You are testing";
And we would have to do this for every object of the WebControls namespace that we use.

The object class of the System namespace is the base class of all classes, the root of the .NET Framework type hierarchy. It exists as a component within the mscorlib.dll file.

It is critical when developing in the .NET environment to understand how the classes are deployed. The polymorphism of the components is the best way to break the ice. From this study you can branch out into the concepts of overriding and overloading members of base classes and become acquainted with derived classes. Mastering these concepts in my opinion will come from practice with interfaces, inheritance and abstraction. From what I have seen, the whole class concept and class initialization is analogous to C++. It is, however, much more advanced than the C++ I was working with on a DEC Alpha Unix box in college. But the concepts haven't changed.

Again I refer to the .NET Framework users guide. I cannot go beyond the scope of the application we are already playing with to exemplify the concepts of the classes…understanding the things I mention above requires study and practice. Lookup "Polymorphism in components," and take it from there.

However, we can see some instances of inheritance implementation at work in our existing project. For example, this line of code:

public class WebForm2 : System.Web.UI.Page
declares the public class that is our Web form and derives from an existing class within the System.Web.UI namespace, the Page class. In C#, you can use this approach for both interface implementation and class derivation. In VB, you would be using the implements keyword. Yes, we could change that line of code to:
public class WebForm2 : Page
and it would work just the same, since we have already declared the System.Web.UI namespace in the beginning of the Web form. Notice the method that exists in the Web Form Designer-generated code region of the Web form:
override protected void OnInit(EventArgs e)
  { …
This method represents a member of the base Page class that we are deriving from, which in the base class inherits from the Control class of the same namespace. Technically, this member can be referred to as Control.Init(). A look at the Page class members shows us the declaration of this method:
 protected virtual void OnInit(EventArgs e);
Alas, we find a virtual method…that is, a member that by type expects to be overridden. Upon invoking a virtual method, that run-time type of the object is checked for an overriding member. The overriding member in the most derived class (that's us) is called. Perhaps more examples on this subject tomorrow. I am thinking a good demo might be to create a new class to carry out the task of passing values between pages, as we have already done within our pre-defined classes of the Web form. It would be a great way to define the process of creating the class and to compile it into a component within a DLL, adding a reference to it for our project, then utilizing it.
Posted by Andrew Young Key points of ASP.NET: The page event cycle
22 SEP 2005 02:17 EDT (06:17, GMT)
There are so many components of ASP.NET that it would be impossible to cover all of them here without confusing the entire discussion and simply regurgitating about items that I have no experience using. I have learned from the applications that I have worked with in this context some of the most important factors to consider and become familiar with. One of them is clearly grasping and understanding how the namespaces work. This is the core of the development infrastructure. Let's not put the cart before the horse, or the hen before the egg for that matter, though. Let's look at a basic, but necessary and powerful, ability within ASP.NET: the page event cycle

An understanding of the page event life cycle is entirely relevant and worthy of some discussion. ASP.NET forms are, by design, adhering to a built-in cycle of events that always occur in the same order. This affects, or can influence, both the performance and functionality of the application. Whenever I see a built-in processing sequence, I know that it is there for good reason and can potentially become a powerful tool in my application. These events occur in the following order: Page_Init, Page_Load, Control events and Page_Unload. The Page_Init event initializes Web server controls on the page. Page_Load runs every time the page is requested. Control events run all change events, such as textbox or datagrid changes, and action events such as button clicks. Page_Unload runs when control is passed to another page or when the page is simply closed. These events can be creatively manipulated in such a way that they "jump through hoops" for you.

As an example, let's work with the code generated in a new ASP.NET VB Web project. This code is located in the code-behind page of your new project. Expand the area labeled "Web Form Designer Generated Code" to access the Page_Init subroutine…the Page_Load event is already visible by default.

We have an ASP.NET Web project, which is designed for inherently dynamic applications by nature. Consider for this example that we have two pages in our application, WebForm1 and WebForm2. We will arrive at WebForm2 being supplied with preliminary information from WebForm1. Based upon the information from WebForm1, we are going to create distinct sets of text boxes in WebForm2 and populate them with data. Let's create a text box and a button on WebForm1. We will pass the value of this text box to WebForm2. We are not passing values between pages via a call to the Request object any longer. Web forms are in reality a class. Things are now completely encapsulated. In the code-behind page of WebForm1, we create a public access property within the class that returns a string:

Public ReadOnly Property Property1() As String
        Get
            Return TextBox1.Text
        End Get
End Property
Using the button we created as the event handler, use the transfer method of the server object to advance to the next page, providing the name of that page as the argument:
Server.Transfer("WebForm2.aspx")
Again, each Web form is a class. In the code-behind page of WebForm2, create a global variable that is typed to that class, and instantiate it beneath the class declaration of the WebForm:
Public sPage As WebForm1 = CType(Context.Handler, WebForm1)
It cannot hurt to reference the source page as well. Create an additional page directive within the HTML of WebForm2:
<% @ Reference Page="WebForm1.aspx" %>
Switch to the HTML view in WebForm2, and ensure that the name of your form is Form1. Toggle back to the code-behind page, and add some declarations for the possible dynamic controls:
Protected Form1 As System.Web.UI.HtmlControls.HtmlForm
Protected WithEvents TextBox1 As System.Web.UI.WebControls.TextBox
Protected WithEvents TextBox2 As System.Web.UI.WebControls.TextBox 
Then add some code to the Page_Init and Page_Load events:
Private Sub Page_Init(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles MyBase.Init If sPage.Property1 = "test" Then 'display in upper left TextBox1 = New TextBox TextBox1.ID = "TextBox1" TextBox1.Style("Position") = "Absolute" TextBox1.Style("Top") = "25px" TextBox1.Style("Left") = "100px" Form1.Controls.Add(TextBox1) Else 'display in upper right TextBox2 = New TextBox TextBox2.ID = "TextBox2" TextBox2.Style("Position") = "Absolute" TextBox2.Style("Top") = "25px" TextBox2.Style("Left") = "550px" Form1.Controls.Add(TextBox2) End If 'CODEGEN: This method call is required by the Web Form Designer 'Do not modify it using the code editor. InitializeComponent() End Sub Private Sub Page_Load(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles MyBase.Load If Not Page.IsPostBack Then If sPage.Property1 = "test" Then TextBox1.Text = "You are testing" Else TextBox2.Text = "You are not testing" End If End If End Sub
Build the application, and view WebForm1 in a browser. Typing "test" in the text box and clicking the button brings you to WebForm2, with the text box that we dynamically configured and positioned displayed. Typing anything else in the same text box executes the else condition of our code.

This is a very simple example that can be expanded to perform many more advanced processes. Logging into an application, for example, with ADO.NET integration, or reading usernames and passwords from an external data source. I based a recent project for an online auto warranty company on this functionality. The make and model of the auto selected in WebForm1 acted to determine which dataset to fill and bind to several listboxes in WebForm2, such as potential prices and available coverages for that vehicle, pulling the information from a SQL box. I should go into the significance of the postback operation, but I am too tired...tomorrow. Good night.
Posted by Andrew Young ASP.NET
20 SEP 2005 00:00 EDT (04:00, GMT)
Windows application development was previously an area restricted to C and/or C++ developers. The .NET framework allows developers to leverage their existing skills to develop pretty much any type of application. Even Java developers will see familiar code when they create C# ASP.NET Web applications. For our ASP.NET topic, the two languages we will use are VB and C#. All languages support by the .NET framework offer the same performance, essentially. It is a matter of preference which language you choose to use. When compiled, the .NET-based language will be converted to Microsoft Intermediate Language (MSIL). MSIL is then compiled to native code by the same compiler at runtime. In other words, the MSIL is handled by the runtime. The common language runtime is language and platform-independent. The runtime uses a JIT compiler to process the MSIL-generated code into native code (another Java-induced concept). At this point, the compiled code is cached so it does not need to be recompiled for each request. The runtime is a managed environment…garbage collection and security is automatically provided. You do not need to create destructors within your classes. With this approach and the use of the now industry-standard XML, we as developers can spend a lot less time considering compatibility issues and more time on the logic of our applications.

For what I have used it for thus far, I love working with Visual Studio.NET. It is a rich, streamlined IDE that allows excellent drag and drop functionality of any object you can imagine. I have only loved one other IDE in my life, that being the Lotus Domino Designer…and I cannot really compare the two. I will say, though, that I favor the Microsoft approach in terms of the way that they have maintained and extended VB for Web development. IBM should be doing the same for their LotusScript developers, the core of that development community. Perhaps they have with Domino 7, I haven't had a chance to really look at it as of yet. I do know that they have created an integral component for XML-based Web services, though. Anyway, that is an entirely separate discussion so let me stop rambling.

The .NET framework, simply stated, consists of namespaces (DLLs) or class libraries. This is an extensive collection of reusable data types. It is worth noting that namespaces are arranged hierarchically for ease of reference. You can add to this library, which essentially creates for us, as developers, exposure to the design of our own .NET framework. Creating a class library creates an actual DLL file. All you need to do to access this component from other programs is add a reference to that DLL, then instantiate the reference via its namespace and class name. We will go into some examples of this tomorrow.



Posted by Andrew Young Summation and a troubleshooting tip
19 SEP 2005 22:38 EDT (02:38, GMT)
I have found that most errors are related to connection objects and incorrect paths or permissions. Remember that your server MUST have access to your database in order to perform actions on it. This access is granted via the IUSR_<IIS servername> username. If you are using a different backend data source, such as SQL, you must pass a valid username and password to the SQL database if it is password protected.

There are built-in server variables available that will assist in you in troubleshooting connection issues. One specific server variable is the "PATH_INFO" variable. As an example, the code below represents a page that will help to resolve the path to your database. Place this page in the same directory as your database, and view it in your browser. It will display the relative and absolute paths. From there, you can copy the absolute path displayed to your connection string. Remember to remove the name of the ASP page from the string (as it will be displaying whatever you name the page below) and replace it with the name of your database.

<html><head><title>Path Information</title></head><body>
<% Dim pathinfo, physicalpath
pathinfo = Request.ServerVariables("PATH_INFO")
physicalpath = Server.MapPath(pathinfo) %>
<b>The relative path to the file is:<br><% = pathinfo %><br>
<br>The physical path to the file is:<br><% = physicalpath %><br><br>
</b></body></html>
Sending dynamic e-mail messages via ASP is done through the CDONTS (Collaborative Data Objects) component. This is not an out-of-the-box feature. CDONTS is installed when you add the SMTP server service. The following code creates and sends e-mail via CDONTS:
<% Dim objMailUser ,bodyStringUser
Set objMailUser = CreateObject("CDONTS.NewMail")
'(build the body of the email …)
bodyStringUser = "This email is a confirmation for your recent CD-ROM request." &
Chr(10)& Chr(10) bodyStringUser = bodyStringUser & "Your Order ID is: " & Session.SessionID &
Chr(10) & Chr(10) objMailUser.MailFormat = 1 objMailUser.From = "webmaster@mycompany.com" objMailUser.To = Session.Contents("email") objMailUser.Subject = "Receipt for your CD-Request" objMailUser.Body = bodyStringUser objMailUser.Send Set objMailUser = Nothing Session.abandon %>
Suddenly, one day a short time ago, it became time for a dreaded upgrade. We had already upgraded the NT servers to Windows 2003 servers. With that complete, our network admin went live with the application we have been discussing and several others as well, now on IIS 6.0. Suddenly, the pages generated errors. I must admit that, yes, I did not research compatibility. After some troubleshooting, I narrowed the problem down to the CDONTS code. It turns out that CDONTS is now obsolete in the .NET framework. All other code works fine. CDONTS has been superseded by CDOSYS. You can migrate CDONTS to your 2003 server, as described here. You can find a great breakdown of CDOSYS here. I opted to convert the code to CDOSYS (the build of the body remains the same so it has been omitted).
'new code added on 6/23/2005
'IIS 6.0 does not support CDONTS, CDOSYS is the successor
'this code is a migration to CDOSYS - A. Young
Dim iMsgUser
Set iMsgUser = CreateObject("CDO.Message")
Dim iConf
Set iConf = CreateObject("CDO.Configuration")

Dim Flds
Set Flds = iConf.Fields
Flds("http://schemas.microsoft.com/cdo/configuration/sendusing") = 1
Flds( _
 "http://schemas.microsoft.com/cdo/configuration/smtpserverpickupdirectory") _
  = "c:inetpubmailrootpickup"
Flds.Update

Set iMsgUser.Configuration = iConf
iMsgUser.To = Session.Contents("email")
iMsgUser.From = "webmaster@mycompany.com"
iMsgUSer.Subject = "New CD-Request"
iMsgUser.TextBody = bodyStringUser
iMsgUser.Send          
There are many other aspects to ASP that we have not covered and that I have not even used. I definitely do not claim to be a "master" of ASP. Like any other technology, I try to develop an understanding of the basics and not be intimidated by all the cryptic abbreviations. To me, it's the same as when I was a kid and got my first erector set. I started by just learning how to build little parts, then found my mind wandering, thinking of new shapes, new sizes I could create and thinking through how to go about it now that I knew the basic concept. I wonder if they still sell those things…

Preferably a need will arise and your development will not be just for practice. Taking it in small doses and testing each function as you go, will allow you to be successful and not get discouraged. As it is with ASP.NET, there is minimal to no learning curve when it comes to LotusScript or VB developers. It's just a matter of getting to know the objects and how they are applied. On that note and in conclusion of the ASP discussion, the ASP Object Model:



Posted by Andrew Young Script integration -- server-side, client-side and ADO, part 4
16 SEP 2005 21:28 EDT (01:28, GMT)
Continued from yesterday's entry…

From this point, it is simple. The code of the cdadminupdate.asp page will use a duplicate approach. Now that we have stored all of our data in precisely named application variables, we have a copy of each selected record in memory. When the update button of this page is clicked, we initiate the next page. Again, we look at our "isValidated" Session variable (here it prevents someone from attempting to access the page directly without logging into the application). Next we ensure that at least one record has been selected. If not, we do not need a refreshed page, so we use the back method of the history object to return to the previous page. (Again, I like the appearance of the Msgbox, and, at this point, it maintains uniformity in code and for the end user.) We use the variable where we stored our total iterations ("totalRecords"):

  Response.Buffer = "true"
  Dim checkBox, name, email, fullAddress, address, sessID, signup, checkString
  Dim recNumCheck, recInx, actArchive
  if Session.Contents("totalRecords") = 0 then %>
 <script language="vbscript"> 
    Msgbox "There are no records to update." & Chr(10) & "You will now be returned to the
CD-Orders Page.", 16, "Error" document.write(history.back()) </script> <% end if …
Now we can build the header for the dynamic table that will display the data that represents the records to be archived. Notice that all string variables above match those used in the previous page. Only the integer variable names have changed, as they will be used for comparisons and loop arguments. The recInx variable will be our equivalent to the recNum variable of the requesting page. recNumCheck will be assigned the session variable that contains our total of iterations. Since we have already gathered all of the selected records in the application variables, we do not even need to open the active cdorders table. We are going to add them to the archivecdorders table. We are going to use a Do…While loop, using recInx (from 1 to n), until it is equal to recNumCheck (total of iterations from previous construct). The key is to duplicate the iteration…we are simply reversing the transfer. Instead of writing data from the backend database to the application variables, we are now writing the application variables to another table in the back-end database:
  recNumCheck = Session.Contents("totalRecords")
 'archive selected records
  Do While recInx <= recNumCheck
  recInx = recInx + 1
  checkBox = "checkBox" & Cstr(recInx)
  name = "name" & Cstr(recInx)
  email = "email" & Cstr(recInx)…
   If Request.Form(checkBox)= "Yes" Then
   actArchive = actArchive + 1
   RS1.AddNew %>
         <tr><td width = "20%"><font size="2"><center><% = Application(name)%></center></font></td>
    <% RS1("name") = Application(name)%>
<td width = "20%"><font size="2"><center>…  %></center></font></td>
    <% RS1("sessID") = Application(sessID)%>
<td width = "10%"><font size="2"><center><% = Application(signup)%></center></font></td></tr>
    <% RS1("signup") = Application(signup)
    RS1("datefilled") =  Date()  
    RS1.Update
      RS1.Movenext
   End If   
  Loop
RS1.Close
set RS1 = nothing %>
</table>
As you can see, it is the exact same naming convention as the page that originally built the variables. It is, therefore, self-explanatory. The actArchive variable is used to return to the browser the number of records that were archived. Notice that we are using the AddNew and Update methods to create the new record. There is a ton of documentation on using the Execute method, with some other pre-defined parameters, to achieve the same thing. I strongly urge you to avoid attempting to use the Execute method. I have found it to be totally inefficient.

Now we must open the active cdorders table and delete the records that we have now archived. Since we are using the same database in the same location, we do not need to recreate our C1 connection object. It is still open and pointed to our database…we just switch back to the active table:

recInx = 0
'now delete these records from the cdorders database
SQL = "SELECT * FROM cdorders"
RS1.Open SQL,CS,adOpenDynamic,adLockkOptimistic,adCmdText
Do While recInx <= recNumCheck
  recInx = recInx + 1
  checkBox = "checkBox" & Cstr(recInx)
  sessID = "sessID" & Cstr(recInx)
If Request.Form(checkBox)= "Yes" Then
If RS1("sessID") = Application(sessID) Then
RS1.Delete
RS1.Update
…
RS1.movenext
End If
Loop
Tomorrow I will try to follow through on the flowchart that I promised on the ASP Object Model, and I'll also briefly cover CDONTS and how Microsoft superseded it with CDOSYS without warning (in fairness, that is, without any warning that I was aware of) and did not make IIS 6.0 backward-compatible with CDONTS…Leaving us all with unexpected and initially unresolved page errors upon upgrading to IIS 6.0.
Posted by Andrew Young Script integration -- server-side, client-side and ADO, part 3
15 SEP 2005 22:48 EDT (02:48, GMT)
Building a dynamic table with ADO data and HTML
Having concluded yesterday's discussion and established a valid login, we can now perform the next task: building an HTML table dynamically sized to the number of records within the specified Access table. Included with the specification of this project was the ability to delete selected records from the database via the ASP page. The script to actually delete the records is well defined, but how do we know which records are marked in the page for deletion? I looked at some ideas, but what I found at that time did not provide the ability to select multiple records for deletion. This is where the "one key advantage" of the ASP.NET dataset over the ASP recordset that I mentioned in a previous blog comes into play. It is much easier using Visual Studio.NET to create this ability than it was to do it manually using Visual InterDev. Again, we will look further at that functionality in the ASP.NET discussion.

The current task will involve both adding records to and deleting records from the database tables. We needed to maintain an archive of fulfilled records; therefore, the records that we are "deleting" from the active orders table (cdorders) is first being moved to the archive table (archivecdorders), then deleted from the active table.

I finally concluded that there was no simple way to do this. Perhaps there were UI elements in Front Page or Dreamweaver that might have helped, but I was definitely not ready to accept the overhead that either of those tools would add to the code.

I built the dynamic table mentioned above, along with a checkbox to the left of each record retrieved from the database. You might have noticed one variable that was declared yesterday that was not mentioned…the "recNum" variable, which will be an integer value. In order to know which checkbox was selected, I needed to name them according to the record they represented (a server-side variable recognized by the client as an HTML field). We begin by welcoming the user by login name, with an alert that a timeout will occur after 20 minutes of inactivity. This value is set by the timeout property of the Session object and it is the default. You can alter it with the following syntax:

<Session.Timeout = timeout in minutes>
Next we build the header of the table and begin iteration:
<% Else %>
  <p align="center"><b>Welcome, <% = Session.Contents("userName")%>. Your login will remain
valid for all administration pages.
If you are inactive for a period exceeding 20 minutes, your
session will timeout and you
will need to login again. If you should close your browser, you will
also need to login again.</b><br><br> <table border=1 cellspacing=0 cellpadding=5 width="100%" align="center"
bordercolor="#000099"><font size="1"> <tr><td width = "10%" bgcolor="#CCCCCC"><font
size="2"><b><center>Filled<center></b></td><td width = "20%"
bgcolor="#CCCCCC"><font size="2"><b><center>Name</center… <% do until RS1.EOF recNum = recNum + 1 checkBox = "checkBox" & Cstr(recNum) %>
Creating awareness of the records being displayed
We begin with a do loop to iterate until EOF (end of file). "recNum" is defaulted to 0, but we want to set it to 1 immediately to make things easier to follow. The variable "checkBox" stores the string checkBox1. That string variable will be the HTML field name of the first checkbox and will be assigned to the client-side code via the write method of the response object:
<tr><td width = "10%"><font size="2"><center>Yes<input type="checkbox" value="Yes"
name=<%Response.write(checkBox)%>></center></font></td>
Our recNum variable will increment by 1 and create a new HTML checkbox field, named checkBox1, checkBox2, till checkboxn with each loop iteration.

Still, that only creates a pointer to the checkbox that has been selected. If selected, then checkboxn will equal "Yes." So we have selected checkBox1, for example, that tells us that the first record in the display is now marked for archiving. However, using this field name alone is inherently flawed. Consider if others are concurrently performing actions on the database (e.g., adding or deleting records), the recordset may not be correct (the code will not fail to execute, but our actions may be inaccurate). As mentioned previously, our recordset is dynamic as defined by our cursor type, but our variables and/or field names during processing are not. If someone else is concurrently adding a record, the checkbox integer may now point to a different record than the one we selected in the application. The same thing can happen if someone else is concurrently archiving a record. In order to maintain the integrity of the application, it is imperative to create a mechanism that will repeat the approach of the checkboxes and allow us to match the records up with those values in the page specified in the "action" parameter of the form tag that processes the request. We can do this by using application variables to identify the selected records and store them into memory. Application variables, like session variables, are global in scope to your application:

name = "name" & Cstr(recNum)
email = "email" & Cstr(recNum)
address = "address" & Cstr(recNum)
sessID = "sessID" & Cstr(recNum)
signup = "signup" & Cstr(recNum) 
company = "company" & Cstr(recNum)
fullAddress = RS1("streetAddress") & " " & RS1("city") & " , " & RS1("state") & " " &
RS1("zipcode") & " - " & RS1("country")
"Name" is now a string variable -- "name1", "name2" and so on. The approach is the same for each variable listed above. We are going to use the names of the application variables as our field names within the dynamic table. The sessID variable is also worth a quick mention. Each time an ASP application is started, an ID is created for the session and this value is unique. It is accessible via the ID property of the session object, (Session.ID). This value was used in this application as an identifier for each record when it was created and was stored with the record in the access table and returned to the user as the order number.

Having established this initial set of local variables to begin the iteration, we can begin using them to create a set of application variables that will store each bit of data for each record as it is displayed. We have an integration of server-side code with HTML. Notice the application variable names -- they are not enclosed in quotes. We are creating each application variable with the name that we created and stored in each string variable. So we have Application("name1"), Application("email1"), Application("address1"), etc. Each iteration will create a set of new variables -- Application("name2"), Application("email2") and so on -- until all data is completely stored within these variables. We are also writing the value of each corresponding field from the backend database to the HTML table as we go. Notice that we create a new session variable, "totalRecords," which stores the integer total representing our number of iterations (records). Essentially what we are doing is using dynamically named application variables in place of HTML field names.

A snippet of this code is below:

<tr><td width = "10%"><font size="2"><center>Yes<input type="checkbox" value="Yes"
name=<%Response.write(checkBox)%>></center></font></td> <td width = "20%"><font size="2"><center><% = RS1("name")
%>
</center></font></td> <% Application(name) = RS1("name") %> <td width = "20%"><font size="2"><center><% = RS1("email") %></center></font></td> %></center></font></td> <% Application(email) = RS1("email") %>…… RS1.movenext loop <close the objects here>….. Session.Contents("totalRecords") = recNum %> </table>
Stay tuned to tomorrow's blog entry for more…
Posted by Andrew Young Script integration -- server-side, client-side and ADO, part 2
14 SEP 2005 17:48 EDT (21:48, GMT)
A simple way to use ASP as a login application
Below, we have the code that processes the requesting page from yesterday's blog entry, along with the contents of the SSI file "adoitems.inc." I must again emphasize why I am opting to use an SSI file rather than just declaring and instantiating these objects within the current ASP page. If you are going to use the database with other pages, you will only have to update information in one location if anything changes. For example, if the name or location of the database is changed, you only have to change that information in one central location; the SSI file, rather than weeding through all of your pages haphazardly and searching through your code for necessary updates. The rest of the code will work without a blink.

The server-side code below is in blue, and the client-side code is in violet. The explicit option forces variables to be declared and is not required; it simply helps to create clean coding practices. We are using the "Form" collection of the "Request" object, which holds all the form information from the previous page in the application. We are assigning the values that we retrieve to local variables.

Next we must look at the contents of the "adoobjects.inc" file. Here, we are instantiating the ADO objects we will use to read data from an external data source. We can use the "create" method of the "server" object to instantiate all of these object references.

Connection strings and recordsets
Let's examine these statements from the SSI file:

"Dim CS, DRV, DBQ, C1, RS1
DRV = "Driver={Microsoft Access Driver (*.mdb)}; "
DBQ = "DBQ= C:\weborders\admins.mdb;"  "
There are many others ways to establish these references, but this is the easiest and most efficient. You can create a direct reference in the System DSN and use that value as a parameter when opening the connection, but what if that reference is removed from the System DSN at some point? Your application will fail. It really makes no sense to open a connection in this manner.

We are examining the most basic of connection strings -- to an Access database. It consists of three parts.

  1. The first part is the variable (DRV), which holds the connection string.
  2. The second part is the name of the driver.
  3. The third part is the physical location of the Access database.
We can connect to any data source available in the system DSN -- be it SQL Server, Oracle, Excel, Visual FoxPro, etc. Of course, if the data source you are referencing is associated with a username and password, you must pass that information as parameters when you request to open that connection. (You can, again, pass the username and password from the previous page as these parameters, since they are accessible via in the current page as explained above.)

Next, we can append the location of the database (DBQ) to the name of the driver (DRV), thereby finishing the required parameter for a connection string:

"CS = DRV & DBQ"
We are almost there. Now we declare a variable to establish the actual connection and instantiate it, and follow that by instantiating a recordset object.
"set C1 = server.CreateObject("ADODB.connection")
set RS1 = server.CreateObject("ADODB.recordset")"
The connection and recordset objects have been superseded in ASP.NET by data adapters and datasets (more on that when we get into the ASP.NET discussion). Later in this example, we will examine one of the key advantages of the dataset over the recordset.

Having established our connections in the SSI file, we go back to the ASP file below and perform the following actions.

  1. First, we open our connection to the data source, passing our connection string variable (CS) as the parameter.
  2. Next, we write a simple SQL command to retrieve all of that data contained within the "cdadmins" table of the database.
  3. Finally, we open our recordset. We pass parameters for the simple SQL query and the connection string.
Other parameters are sent to indicate the cursorType, LockType and CommandType. AdCmdText indicates that the command passed is a SQL statement. By default, the recordset is opened as read-only. Therefore, we could have excluded the cursorType in this example, but I thought it was worth mentioning. Specifying adOpenDynamic as our cursor type creates a dynamic recordset object. This is the most efficient way to navigate within the recordset and also makes any changes to the data within the database immediately available within the recordset. The adLockOptimistic LockType establishes that users accessing the application simultaneously will not receive cryptic error messages resulting from concurrent access.

Now we can test whether the request to access this data is valid. We are using the session object to test whether a session variable that we create, "isValidated," is equal to "Yes." Upon successful login, we set this session variable to "Yes," which will be the condition that we are testing to determine whether the result was affirmed. We could have also use the application object in place of the session object in this example. We are using a do loop statement that will navigate until the end of the recordset or until a matching record (consisting of the username and password retrieving from the requesting page) is found. We are preceding the do loop with a test of the "isValidated" session variable, as it would be unnecessary to require a user to log in again if they use hyperlinks on the page to jump to other administrative pages. This condition is applied in this manner to other areas that would require a login as well, so that the administrator will not be continuously prompted to log in to the application.

The conditional statement

"if (RS1("userName") = userName) And (RS1("password") = password) Then"
provides an example of reading the fields of the current record in the recordset, which are fields in the Access database table. Upon completion, successful or not, we close the object references. You must close the recordset object before closing the connection object, or you will generate errors. You have the option of using an SSI file to do this as well.

The next line of code is the final line of inline script that performs the validation:

If Session.Contents("isValidated") <> "Yes" Then %>
as indicated by the closing tag: "%>". This is where we encounter an example of inline server-side script acting to determine whether a client-side script will execute. If the validation has been met, this client-side code will never be recognized. The ability to integrate these scripts is powerful. One might argue that the redirect method of the response object would be a simpler solution here. As you can see, we are using the meta tag written directly to the browser to return us to the previous page. Why? For this application to be correct, we do not want to return to a cached page. Using the redirect method of the response object, you are returned to the login page, and the previous login data is still visible in the two fields. Using the client-side redirection, the page is entirely refreshed. (Also, I like the look and feel of the VBscript Msgbox function much better than anything else that can be used in this capacity.) I spent some time attempting to keep this a server-side redirection, with no success on this issue. This is what led me to discover that server-side/client-side script integration of this nature was possible.

Nonetheless, server-side redirection is the better choice whenever possible. Older browsers do not support client-side redirection, which is not much of a consideration these days. However, the ability of the client to disrupt your application is. The client will be able to see changes in the location bar and can potentially stop it. With server-side script, the client cannot stop the redirection.

<!--#include file="adovbs.inc"-->
<!--#include file="adoitems.inc"-->
<% 
option explicit
  Response.Buffer = "true"
  Dim recNum, checkBox, name, email, fullAddress, address, sessID, signup,
userName, password, SQL recNum = 0 userName = Request.Form("txtUserName") password = Request.Form("txtPassword") C1.Open CS SQL = "SELECT * FROM cdadmins" RS1.Open SQL,CS,adOpenDynamic,adLockOptimistic,adCmdText If Session.Contents("isValidated") <> "Yes" Then do until RS1.EOF if (RS1("userName") = userName) And (RS1("password") = password) Then Session.Contents("isValidated") = "Yes" Session.Contents("userName") = RS1("userName") Exit do End if RS1.movenext loop RS1.Close set RS1 = nothing C1.Close set C1 = nothing End if If Session.Contents("isValidated") <> "Yes" Then %>
<script language="vbscript"> Msgbox "You must supply a valid username and password." & Chr(10) &
"You will now be returned to the CD-Administration Login Page.", 16, "Error" document.write("<meta http-equiv='refresh' content='0;url=cdadminlogin.asp'>") </script>
<% Else %> (…write the page):
I will post the contents of the page in the next blog entry, which will show how we can display data from the database within a dynamic table built of HTML and inline script, as well as how we methodically build a system for marking records for deletion. The contents of the "adoitems.inc" file:
<% dim CS, DRV, DBQ, OC, C1, ORS, RS1, OCM 
DRV = "Driver={Microsoft Access Driver (*.mdb)}; "
DBQ = "DBQ= C:\weborders\admins.mdb;"
CS = DRV & DBQ
set C1 = server.CreateObject("ADODB.connection")
set RS1 = server.CreateObject("ADODB.recordset")
%> 

Posted by Andrew Young Script integration -- server-side, client-side and ADO
13 SEP 2005 15:01 EDT (19:01, GMT)
The ASP scripting model works as follows:
  • The browser requests a page
  • The server sends the script to ASP
  • ASP sends the script to the script engine
  • The script engine executes the script
  • The server sends the page to the browser
  • The browser renders the page
ASP incorporates all of the features of server-side scripting and six built-in objects, (see illustration in tomorrow's blog). ASP allows the ability to interact with databases, send e-mail from a Web page, detect browser version, read from and write to the file system, upload files to the server and manage rotating banner ads based upon dynamic criteria, such as cookies detected on the client machine.

The following simple login application will demonstrate how server-side code can be logically integrated with client-side code. Remember that server-side code is not executed in the browser; it is compiled and executed on the server. Therefore, it is not even visible to the client.

First, it is important to note that there is an order of operations in play with code execution. There are two types of server-side scripting methods in ASP; inline scripting and block scripting. Block scripting is indicated by script tags, like client side code, and the only difference is the addition of the "runat" attribute being included in the declaration:

<script language = "vbscript" runat = "server">
response.write "<b>Block script example</b>"
</script>
Inline script code is enclosed within "<% …. %>", the inline script tags:
<%
= "<b>Inline script example</b>"
%>
(Notice the use of "=" rather than typing "response.write." This is shorthand for the same object call.) This code does the same thing that the client side equivalent would accomplish:
<script language = "vbscript">
document.write "<b>Client side script example</b>"
</script>
With a mixture of inline and block scripting within a single page, the inline scripts will always execute first. Only after these scripts have executed will client-side script execute. This point is critical to the successful operation of your application and can be creatively manipulated. You can place server-side scripts anywhere in your page, even in the head section, but you will not improve performance by placing your server-side script at the bottom of the page, since it is run at the server. ASP.NET VB-based Web applications created using Visual Studio.NET automatically create block scripts for server-side scripting (with the exception of page directives), but you can still manually write inline scripts.

There are times when it is convenient to use server-side include (SSI) files. This allows programmers to reuse code for multiple Web pages by simply including the SSI file in their ASP page. You can include headers, footers, standard logos, and even instantiate ADO objects within an SSI file. I have always used a ".inc" extension for my SSI files, but you can use an ASP extension as well. To call the SSI file from your ASP page, you use the absolute or relative path to the file with an include statement. I normally keep the .inc file in the same directory as my application, so the files remain compact and are easy to relocate to another server if required at some future time.

Let's look at page 1 of the following application. I created this to be used by sales administrators for online company information requests from external customers. These pages are only available via the company's intranet. We are going to look at the method for validating a username and password. The usernames and passwords are stored in a Microsoft Access database that resides in a directory on the system root drive of the server. There are no hashing algorithms for the passwords, as the pages are only available to those within the firewall; so enhanced security was not a consideration. A basic means by which to prevent users from simply browsing to the actual list of submitted orders was the requirement. It provides a perfect example of server-/client-side code integration, with the conditions being established via ADO-generated data validation. The first page below will retrieve the username and password for processing by the ASP engine. Notice that all code relevant to our discussion is in red:

<!--#include file="adovbs.inc"-->
<% 
  Response.Buffer = "true"  
%> 

<html>

<head>
  <title>CD-Request Orders Login Page</title>
  <link rel="stylesheet" href="colours.css" type="text/css">
 </head>
 <TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0"
WIDTH="800"> <tr> <TD HEIGHT="90" width="800"
ALIGN="LEFT"> <img src="images/company.gif"><font
face="arial, helvetica" color="#003366"><b>CD-Request Order List
Administration Login</b></font></TD> </tr> </TABLE><br><body> <form action="cdorders.asp" method="POST"
id="form1" name="form1">
<TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0"
WIDTH="30%" align="center"> <tr><td width="15%"><center>Username:</center></td><td
width="50%"><input type="text"
name="txtUserName">
</td></tr> <tr><td width="15%"><center>Password:</center></td><td
width="50%"><input type="password"
name="txtPassword">
</td></tr><br></table><br> <TABLE CELLPADDING="0" CELLSPACING="0" BORDER="0"
WIDTH="50%" align="center"> <tr bgcolor="#e6e6e6"><td> <font face="arial, helvetica" size="2"
color="red"><center>Please enter your username and
password above. Click Login to validate your entry.<br> <input type="submit"
name="btnSubmit" value="Login" BORDER="0" width="30" height="10">
</font><br> </center></td></tr> </table> </body> </form> <script language="javascript"> document.form1.txtUserName.focus(); </script> </html>
First, you see the use of an SSI file. The adovbs.inc file is a Microsoft system file that defines the ActiveX data objects. Next, we set the buffer property of the response object to true. In later versions of ASP, this is done by default. However, if you are using ASP 2.0, you should set this buffer to true. I developed this application way back then and left it alone. This property set to true will hold the results from the server scripts at the server until all scripts are executed.

Next, the key element of this page is the "form" tag, its "action" parameter, its "method" parameter and its "name" parameter. The "action" parameter points to the next page in the ASP application. This is how ASP pages are tied together to create an application. The "method" parameter set to "post" will send the names and values of the form fields within the TCP/IP packet. The post method will not be available in the location bar of the browser and is therefore the preferred method for sending form information to the server.

Take note of the names of the fields that are used to store the username and password information. The "request" object of the page specified by the "action" parameter to retrieve their values will use these field names in processing their validity.

Finally, we see the code that creates the button to initiate the ASP application. The input type is "Submit." This is required to begin the application. An input type of button can be used, but would require otherwise unnecessary parameters. Also note that the client-side script to set the cursor to the username field is written in JavaScript. It is often preferred to use JavaScript for client-side scripting when possible, as it is compatible with a wider host of browsers than VBscript.

Tomorrow, we will examine the ASP file that processes this form information, which brings us to the meat and potatoes of the application.
Posted by Andrew Young Server-side scripting: An ASP overview
12 SEP 2005 06:58 EDT (10:58, GMT)
Hello, and thanks to all whom have taken the time to submit questions already. If you do not see an answer to your question within a day or so, it is likely I am testing the answer that I am providing prior to actually offering it as a solution. Almost 100% of what I do is geared toward business solutions, not research or study. So if I encounter questions that pertain to solutions that have not arisen in my own endeavors, I will construct the best possible answer that I can and post it at that time when I know it is accurate. I am looking forward to increasing my own experience based upon your questions.

Let me begin my time here with a little history. I was first introduced to ASP in September of 2001, when it became the core technology of my last undergraduate CS class. While I was excited about the class, I did not have high expectations, as the perception of Web development at the time among our professors was somewhat negative. They viewed Web coding as a novice form of development, and, of course, this perception filtered down to us, the students. But after enduring almost four years of some very dry (but, in retrospect, very necessary) CS concepts practiced in C++ using a VI text editor, I, for one, was open to change. This turned out to be one of the most productive classes I have ever taken. I immediately realized the great potential of ASP:

  • To be able to maintain a consistent state between a client and server via a browser,
  • To create multi-page applications to run via the browser with the ability to read from, and write to, external data sources via ADO and
  • To compose dynamic e-mail messages via CDONTS.
To me, ASP represented the ability to create seamless, dynamic applications with minimal investment for the customer or for me. The client is the browser, and the engine is IIS, which every business with at least one Windows server will have, sometimes unbeknownst to them. So what we have is, essentially, a free client/server environment. ASP is an Internet server application programming interface (ISAPI) application, as is ASP.NET, so as long as your Web server is ISAPI-compliant and has the ASP and script engines installed, your applications should work.

I have since learned that the term ASP is a catch-all phrase. It basically refers to pages that contain server-side scripts, but it is commonly used to refer to server-side scripting technology as a whole. An ASP application consists of multiple ASP pages and includes a global application file called "global.asa." This file defines the application and allows you to tie the pages together so that information can be shared across them. This concept has not changed with ASP.NET, but it has evolved. Basically, ASP.NET consists of the same file components, with an "x" appended to them. For example, the "global.asa" file is now "global.asax".

ASP technology also has many built-in objects. They are referred to as the "ASP Object Model," which consists of the Request, Response, Session, Application, Server and ASPError objects. The ASP Object Model consists of server-side entities, as opposed to the Document Object Model (see illustration below), which is a client-side entity. You can, however, integrate your client-side scripts with built-in objects from the ASP Object Model, which we will look at with some later examples.

I think it is best to begin with the basics on this blog, for those who may be new to this technology, and introduce more advanced concepts as the time progresses. With the standard ASP topic, I will talk about scripting languages on the server and on the client with an emphasis on their integration, accompanied by the topics that arise from that discussion. When we get into ASP.NET, I will be discussing the technology in a slightly different way, as the Visual Studio.NET platform becomes a major topic of the discussion. We will start with basics, like creating an ASP.NET Web form, debugging, accessing relational data and finally reading, writing, creating and consuming XML data and Web services with a very cool example I hope to present if I can obtain permission.

The default scripting language is VB script. I formed a habit during the undergraduate learning process mentioned previously: I am most comfortable writing code in Notepad, as my first and most extensive code endeavors were done using a Unix text editor, which is very similar (in that you start with a complete blank). When I discovered Visual InterDev of Visual Studio 6.0, I found an IDE that allowed me to maintain that habit with the addition of automatic color-coding for my script tags, be it block tags, HTML tags or inline script tags. Yes, rapid application development was not exactly being fulfilled, but I was writing every line of code, and I somewhat like it that way. I have used third-party tools such as Dreamweaver and FrontPage, but I found when I looked at the code being generated in HTML, hundreds of lines were being created that were altogether unnecessary for my purposes. And they sometimes generated page errors. Not to mention, there were no front-end UI tools that helped me to create back-end connections to external data sources (i.e., instantiate calls to ADO objects). I think many developers can identify with one another in that we do not like to fix things that are not broken, especially in the software development methods that we have learned to trust.

I am primarily a Lotus/Domino developer, with advanced application certification in both R5 and Domino 6. My advanced certification is based upon LotusScript, which is altogether similar to VB script. When I saw VB script for the first time during that semester, I felt immediately at home. I also realized that I could use my object-oriented programming background (data hiding, encapsulation) in this context. Most developers agree that if you can thoroughly grasp one language -- especially C++ and its stringent use of pointers, etc. -- all languages that follow are relatively easy to learn. This was certainly the case when it came to learning VB script. It is rare in the development field when all things fall into place seemingly on their own. Here I was, though, with a language I was already familiar with, a choice of simple ideas with no learning curve, a free client/server environment to work with and some projects to work on. With the next entry I will delve into actual applications and provide another illustration, this one of the ASP Object Model.



Posted by Andrew Young

MOST RECENT BLOG TOPIC ENTRIES
NOV 2008
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30            
PREVIOUS ENTRIES OTHER BLOG TOPICS
HomeExperts on DemandIT Expert Webcast SeriesExpert KnowledgebaseSite Index
TechTarget provides enterprise IT professionals with the information they need to perform their jobs - from developing strategy, to making cost-effective IT purchase decisions and managing their organizations' IT projects - with its network of technology-specific Web sites, events and magazines.

TechTarget Corporate Web Site  |  Media Kits  |  Reprints  |  RSS  |  Site Map




All Rights Reserved, Copyright 2008, TechTarget | Read our Privacy Policy
  TechTarget - The IT Media ROI Experts