I spend a great deal of time supporting Web Forms developers, especially new ones, on www.asp.net. The aspect of Web Forms development that causes the greatest confusion for new Web developers is not understanding where ASP.NET code actually executes.
A common scenario is this: A new Web developer has developed his first Web Form, and among the seemingly trivial things that he attempts is to display some feedback using the MessageBox.Show method. MessageBox.Show is a method used in Windows Forms applications to display a very simple message box. Depending on the developer, either of the following problems could occur:
The code does not compile, with the complaint that the name MessageBox does not exist in the current context.
The developer added a using line to the code and a reference to the Web site so that the System.Windows.Forms namespace (where MessageBox is located) is recognized and the code compiles, but it does not show a message box.
This example uses the MessageBox.Show method, but any number of other methods commonly used in Windows Forms applications just do not make sense in a Web Forms application. The following sidebar titled "What's Done Where?" addresses the underlying reason why a message box cannot be implemented directly in ASP.NET code.
The actions taking place and where those actions are taking place when a Web page is requested are shown in the following table.
Step | Action on the Server | Action on the Client |
---|---|---|
User requests page | Nothing | User types URL |
ASP.NET builds HTML | C# code is executed and page is parsed | Nothing |
User sees content | Nothing | Browser displays content |
The important part of this sequence of events is that when the C# code is executed, it is executed on the server. Although the client and server can in some cases be the same machine, that is not normally the case. The new Web Forms developer who manages to get a Web Forms application that calls the MessageBox.Show method to compile might get a message box to appear, but it will not appear where the developer wants it to, on the client.
If the changes required for the page to run are made, and the page compiles, why would the message box not appear on the server where the code is executing? To understand the answer, you need to know a little about the way that Windows commonly runs services.
When you are developing an ASP.NET page, you will almost certainly be sitting right at the server as the page runs. However, when a real Web application is running, it is very likely that no one will be sitting at the server when the application is accessed. Often the machine running a Web page is at a remote site, often a site where a server or a portion of a server is rented with good, public Internet access. In these situations, having the Web server running and displaying messages is more than just not helpful, it can actually be detrimental to the function of the application. For instance, imagine that our Web Form with the call to the MessageBox.Show method actually did run and display a message box on the server. If no one is there to see it, what should happen to the application? MessageBox.Show is a blocking call. That means that it will wait, or block, in this case waiting for user input. Blocking is not good when you are running a Web server. However, more important than what would happen if the message box were to appear on the server is the fact that the message box will not appear on the server.
Why is this so? If our Web application is able to display a message box while server-side code is running, the message box is displayed on a virtual console that will not be visible, even to a user who might be sitting in front of the server. Windows services should not try to show any user interface; even if they do, any user interface will be "displayed" in an invisible virtual display rather than on the monitor at the server.
There are other implications of how Windows services run. For instance, every process running on a Windows-based machine runs under some user context. On the machine I am using to write this book, I am logged in as the user "XEON\Doug," which means that I am user Doug on a machine named XEON. When I do anything on the machine, Windows checks to ensure that XEON\Doug has rights to perform the task that I'm attempting.
So, how does it work when a Windows service wants to perform some operation on a file or other resource protected by Windows? To control Windows services, you can select Administrative Tools from the Control Panel, and then open Services. In the list of services, you can scroll down to the bottom of the list and double-click the World Wide Web service, which opens a dialog box with four tabs. On the Log On tab, you will see something like this.
A Windows service can either log on using the special Local System account (as my World Wide Web service does), or it can log on as a specific user. The specific user can be a user on the machine or a domain account. In any event, the user you specify here will be the user whose context the World Wide Web service will operate as.
In addition to allowing you to specify the user that the World Wide Web service will operate as, the Log On tab also allows you, if the service is running as the Local System account, to interact with the desktop. Allowing a Windows service to interact with the desktop is almost never a good idea, and in any case the service must be written in a special way to allow such interaction. Services almost never interact with the desktop, and the World Wide Web service is no exception. Leave this check box cleared.
While talking about the World Wide Web service and the ways in which it works, it is important to revisit the New Web Site dialog box last seen in Figure 1-2. When you create a Web site using the File System location, the Web site is not actually created and run using the World Wide Web service. Rather than using a service, Web sites created using this method run in a Web server that runs as a regular user process. Although now bundled into Visual Studio 2005, this Web server was previously distributed as the Cassini Web server. This regular user process does not run the Web page on TCP/IP port 80 (the port Web applications normally use), but instead uses a random port, and the sites created this way are accessible only on the machine where you are debugging the code.
It's important to note that a Web application running in the Visual Studio Web server can access any resources that the user running the application has access to. This can be convenient, but it often leads to applications that work properly when you are developing and debugging the application in Visual Studio, but fail with some security-related problem when they're moved to a "real" Web server.
You can elect to create a Web site in Visual Studio using the Web server. Rather than leaving the Location combo box set to File System, you can change it to HTTP. When you do this, you are prompted to enter a full HTTP path for the Web site (rather than the full file path), as shown in Figure 1-10.
Figure 1-10: The New Web Site dialog box for an HTTP site
When you create a new Web site using an HTTP location, Visual Studio automatically creates the Internet Information Services (IIS) application for you. When you need to deploy the application on a Web server without Visual Studio installed, you will have to manually create the application in IIS. Appendix A, "Creating and Deploying Applications in IIS," explains exactly how to do this.
The ability to create Web sites in Visual Studio in so many ways can lead to some confusion, but this flexibility is necessary. Many corporations will not allow developers to run IIS (which uses the World Wide Web service), and so the easy availability of an alternative way to develop Web sites is important. None of the applications in this book will be affected by the location used for new Web sites.
Note | Displaying a message box is just one of the things that you cannot do using server code. There are a variety of other things that you might be used to doing in a Windows Forms application that you cannot do directly in a Web Forms application. For instance, in a Windows Forms application, you might drop a timer on the form and use the OnTimer event to perform some task (such as updating a grid). Timers that operate on the server will not work as you expect them to. There are alternatives, discussed in the following section. |