|
download source code
Abstract
Web applications are getting more and more complex day by day. With complexity, arise issues like difficulty in development, maintenance and scalability of the application. So in order to develop complex applications we have to keep these problems in mind. Software Engineer's have been searching for a solution to these problems and by analyzing industry data they have developed guidelines for development of such complex applications. Following these guidelines we can ensure that these issues have a minimal impact on our application. This is where architectures come into play. Model-View-Controller (MVC) is the most popular and implemented architecture in industry. This article describes one way of implementing MVC in ASP 3.0.
Introduction
Even after the launch of ASP.NET, classic ASP 3.0 is still being used for web application development. All of the competing web technologies like JSP, ASP.Net or PHP have provided an implementation MVC. MVC makes applications easy to maintain and more scalable. But why did I feel the need to write this article? Well I was going to start work on a web application in ASP and I wanted to implement MVC, and to my utter surprise I found that there was no implementation of MVC in ASP. So this article can be used to develop small or large scale applications in ASP that implement MVC.
So first I give an overview of MVC and how it can be helpful, secondly I develop a very simple application that implements MVC in ASP, and finally I present possible enhancements that can be useful for developing larger applications.
System Requirements
To run the code for this sample you should have
- Windows 2000 or greater
- IIS 5.0 or greater
- Any editor for ASP that you are comfortable with
- MS Access
Installing and Compiling the Sample Code
The sample download for this article contains a zip file. The sample application authenticates a user from database and if authenticated displays user's name and the country he/she belongs to.
MVC
MVC stands for Model-View-Controller. The MVC paradigm was introduced in Smalltalk as a method of architecting GUI's and has since been applied to various areas of application architecture including web applications.
MVC has three components as implied by the name - a controller, model and view. Although these components are logical concepts but usually to make them clearer, applications are physically divided into three components also. The model contains all the business logic in it, including communication with the data access layer. The view renders the model into a form suitable for interaction, typically a user interface element. The controller responds to events, typically user actions, and invokes changes on the model or view as appropriate. A general flow of MVC is as follows:
- user interacts with the user interface in some way (e.g., user presses a button)
- controller receives notification of the user action from the user interface
- controller accesses the model, possibly updating it in a way appropriate to the user's action
- model notifies the view of changes
- view uses the model to generate an appropriate user interface
- user interface waits for further user interactions, which begins the cycle anew
Figure 1 also explains this flow.

Figure 1 - MVC flow
Actions in an application are basically the functionality that it provides e.g.. if it is a shopping cart application than login, add to cart, delete from cart, calculate total or logout could be a few possible actions.
Wrapping up MVC, requests are directed to the controller, which executes a model (if any) associated with this action, and finally executes a view (if any) associated with this action.
The Framework
In MVC all client requests are directed to controller first and then the controller decides which model and view to execute. In our framework this is default.asp though it can be any page as long as it is loaded first and does not have any application related code in it, but only controller code will be present here. Controller code is responsible for retrieving action from request object, comparing it with the actions that have been specified in the controller and then executing the model and view specified against that action.
At the same level in the directory structure there are two folders named model and view. The model folder will contain all ASP pages with only business logic in them, it usually contains communication with the database, calculations and any code specific to domain. . The other folder view contains all the pages and data that will be used for display e.g. asp pages, html pages, style sheets, scripts, images etc. This is all there is to our framework, Figure 2 shows the implementation.

Figure 2 - Our implementation of MVC
The controller compares the action requested against actions specified and, executes the model and view associated with that action.
The Sample Application
The sample application authenticates a user by comparing username and password with the database and if authenticated then displays user's name and the country he/she belongs to by retrieving values from the database. I have kept the sample application simple and small so that the code can be easily understood, since it is going to remain almost same for even larger applications.
When a user connects to the application, he/she is shown the login page. The user enters his username and password and clicks on the submit button.

Figure 3 - Login page
If the user is authenticated by the application then it displays the welcome page that displays user's name and country as shown in Figure 4, otherwise it redirects user back to the login.asp page.

Figure 4 - Welcome page
That's all what the application does.
Database Design
The sample application uses a very simple database called users.mdb. It consists of a single table UsersInfo shown in Figure 5.

Figure 5 - Database design
You can populate it with your and your friend's names or country. It's very simple and all fields are text.
The Code
Now let's look at the code and understand how the framework that we designed works.
In MVC the most important component is the controller since that actually processes all the requests before they are executed. Our controller is the default.asp file.
First of all, you need to retrieve the value of action from the request object; this action informs the controller what to perform next.
action = request("action")
You will need two variables model and view, initialize both model and view variables to an empty string; shortly I will explain why do we need to do this.
model = ""
view = ""
Now you check what is the action requested, as I told earlier that it all depends upon the action which model and view are to be executed next. Actions are basically the functionality that your application performs e.g. the sample application you are developing first authenticates user. So login is the first action that needs to be performed. In the if condition you need to tell what should the application do if the action is empty, that usually happens when the user hits the site first time. Once the user has entered the application then all actions are passed by the application itself. So what's happening here is that you check that if the action is empty or login then the view to be executed is login.asp which was placed in the view folder, after we extracted the source code zip file. Since no prior processing is required therefore we do not need to associate any model with this action otherwise that model would also have been specified here. We also check that if action is empty than it means that page is being accessed without specifying the action i.e. http://localhost/asp-mvc. We know by default IIS loads default.asp page, therefore the action to be taken by the application in this case is login.
if(action="" or action="login")then
view = "./view/login.asp"
end if
Before proceeding further we need to look at a very important method of ASP, server.Execute().The server.Execute() method calls an .asp file, and processes it as if it were part of the calling ASP script. The server.Execute() method is similar to a procedure call in many programming languages.. It takes path of page to be executed as its parameter. The most important property of this method is that the Application, Request, Response, Session and Server variables are available to the page being executed even if set in the calling page. This is where we use the empty initialization of model and view variables, as is the case with login action which does not have any model associated with it, therefore we first check if model is not empty then execute the model. This is required because if we do not initialize the model then server.Execute() would produce an error. Same case is for view. So here we execute the model if any and then view if any and our controller is complete, in our case it displays login.asp.
if(model <> "") then
server.Execute(model)
end if
if(view <> "") then
server.Execute(view)
end if
The user enters his/her username and password and clicks on login button. Now if you look at login.aspI have specified in the form tag that this form should submit to default.asp but this time the action specified in query string is welcome. Remember this action is different from the action of form tag. Why did we redirect the request to default.asp instead of checkLogin.asp directly, this is because default.asp is our controller and all requests are first directed to the controller.
<form name="login" method="post" action="../asp-mvc/default.asp?action=welcome">
The welcome action in our application means that display the user's name and country on a page. But before we do that we need to authenticate the user and only if user is authenticated then display this information to him/her. So to perform this task we add a new condition in our controller and check, if action is welcome then the model is checkLogin.asp and view is welcome.asp.
if(action="" or action="login")then
view = "./view/login.asp"
elseif(action="welcome")then
model = "./model/checkLogin.asp"
view = "./view/welcome.asp"
end if
A model has been added, as you know that model has all the business logic in it that is required to be processed before a view is executed, so in your application model for welcome action is checkLogin.asp. The following code snippet just connects to database and executes a query based upon the values from login.asp. Now a question might arise here in a few minds, how come the values from login.asp page are still save in the request object because login.asp does not directly submit its values to checkLogin.asp. Well it's a valid question and the values are still intact in the request object because in our controller we used server.Execute() which makes sure that values coming to the page with this method are also available to the page which is executed using this method.
'connect to database
Set conn = Server.CreateObject("ADODB.Connection")
Set rs = server.CreateObject ("ADODB.Recordset")
conn.Provider = "Microsoft.Jet.OLEDB.4.0"
conn.ConnectionString = "Data Source=" & Server.MapPath ("users.mdb")
conn.Open
'get values from request object
uid = request.Form("txtUID")
pwd = request.Form("txtPWD")
'execute query and retrieve values
Set rs = conn.execute("SELECT * FROM UsersInfo WHERE uid='" & uid & "' AND pwd='" & pwd & "'")
Now comes the part which makes sure that business logic is kept separate from user interface, so I have used the session object and placed all values that are required by the view to display, in our case this is user's name and country. Arrays can be used for more complex values; right now our only goal is to display two values so we just place them in session object.
'if values were retrieved then save the info in session object for the view
if(rs.eof<>true)then
session("name")=rs("name")
session("country")=rs("country")
else
session("error")="true"
end if
After model is executed complete control is transferred back to the controller. This is a property of server.Execute(), now is the time to execute the view, welcome.asp. We have stored all necessary values in the session and the view gets them and displays them that's all the view does and is supposed to do. To check for errors we place a special variable named error in session that is set to true in model if any error occurs and in view we check it and display data or error message accordingly.
if(session("error") = "true") then
Response.Redirect("./default.asp?action=login")
else
Response.Write("Welcome Mr. " + session("name") + " you live in " + session("country"))
end if
So this makes sure that business logic is kept separate from user interface and any changes in one do not affect other and that is what MVC is all about.
Further Work
This was a very simple framework, therefore I restrained from a few things. For those of you who are really interested in this can enhance this into a full-fledged web framework.
When the number of actions increase the if else structures are going to increase and make the code very lengthy so to overcome this problem XML can be used instead, that describes the model and view to be executed for each action.
<?xml version="1.0" ?>
<actions>
<action value="">
<model>none</model>
<view>login.asp</view>
</action>
<action value="login">
<model>none</model>
<view>login.asp</view>
</action>
<action value="welcome">
<model>checkLogin.asp</model>
<view>welcome.asp</view>
</action>
</actions>
Handling errors using the session object, also handling of session object itself is very important since all data is being saved in the session object.
Conclusion
So you saw that developing large web applications, which are scalable and maintainable, is a problem that needs to be overcome. To overcome these problems we used MVC, a solution used by major competitors in this market. We developed a simple web application that implemented MVC in ASP and at the end I gave a few enhancements that could be used for larger applications.
About the Author
Adeel Javed has a Masters degree in Computer Sciences from University of Central Punjab, Lahore, Pakistan
and currently he is working as a Software Engineer at Systems Limited, Lahore, Pakistan.
He contributes to various open-source projects including
JSide,
Sigma and
JBullet.
|