ASP.NET "Hello, World" without web controls
(plain GET and POST)

I originally posted this on codeproject.com, where it was edited beyond my control. These are my words, with updates.

- Matthew

Introduction

Call me a Luddite, but I usually look for the most low-level, versatile way to solve a problem that doesn't require learning the idiosyncrasies of some new framework. I often prefer the command line to a GUI, I prefer a text editor to a WYSIWYG editor for web pages, and I used to program mainly in C. With respect to programming, I finally caved and realized the benefits of C#. So, now I'm using it for desktop applications and web development. This naturally leads to using ASP.NET.

There are some things I like about ASP.NET and some that turn me off.

What I like:

What turns me off:

After using web controls for a little while, recently I wanted to make a simple web page that took some user input and produced some dynamic output, and I wanted to avoid most of that complexity. I wanted to use a plain HTML <form> element (I.e. without runat="server") and HTTP GET and POST variables instead of ASP.NET event callback functions and view state, but I still wanted to use .NET, C#, and code render blocks. Included are a couple simple pages that do this.

Note: do not mistake that many states of the page life cycle are still running in these pages. I even hook Page_Load (and I have hooked Page_Unload in a page I'm writing right now.) My goal was not to write something completely raw but to write something reasonably raw and streamlined but also reasonably simple and straightforward. ASP.NET isn't all bad, and by avoiding web controls and any special mechanisms of the Page class, I can concentrate on plain HTTP/HTML/CSS/JavaScript, and most aspects of what to me is an overly complicated page life cycle become irrelevant. I.e. I no longer have to worry about Page_PreInit, Page_Init, Page_InitComplete, Page_PreLoad, Page_LoadComplete, Page_PreRender, or Page_SaveStateComplete; the IsPostBack flag; view state; or control events.

The code

In the GET example, user input becomes part of the URL and can be persisted through hidden form fields. The key .NET mechanisms are Request.QueryString for input and Response.Write for output.

The POST example is almost exactly the same as GET with minor differences. Of course the URL does not store the input. Instead of Request.QueryString, Request.Form is used to access it. Finally, instead of the method attribute of the form being get, it is post. Input can still be persisted through hidden form fields (or cookies, but I didn't use this method).

In both cases, HttpUtility.HtmlEncode is used to escape the re-output of arbitrary user input, so that characters like & are escaped to valid HTML &amp;


HTTP GET with ASP.NET:

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <title>HTTP GET test</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8"/>

        <script runat="server" language="C#">

            private string prev_first_name;
            private string first_name;
            private string prev_last_name;
            private string last_name;

            private void Page_Load()
            {
                prev_first_name = Request.QueryString["prev_first_name"];
                first_name = Request.QueryString["first_name"];
                prev_last_name = Request.QueryString["prev_last_name"];
                last_name = Request.QueryString["last_name"];
            }

            private void WriteDisplay()
            {
                Response.Write(
                    Environment.NewLine +
                    "Previous first name entered: \"" +
                    HttpUtility.HtmlEncode(prev_first_name) +
                    "\"<br/>"
                );
                Response.Write(
                    Environment.NewLine +
                    "First name entered: \"" +
                    HttpUtility.HtmlEncode(first_name) +
                    "\"<br/>"
                );

                Response.Write(
                    Environment.NewLine +
                    "Previous last name entered: \"" +
                    HttpUtility.HtmlEncode(prev_last_name) +
                    "\"<br/>"
                );
                Response.Write(
                    Environment.NewLine +
                    "Last name entered: \"" +
                    HttpUtility.HtmlEncode(last_name) +
                    "\"<br/>"
                );
            }

            private void WritePersistentVars()
            {
                WriteHiddenFormVar("prev_first_name", first_name);
                WriteHiddenFormVar("prev_last_name", last_name);
            }

            private void WriteHiddenFormVar(string name, string value)
            {
                if(value != null)
                {
                    Response.Write(
                        Environment.NewLine +
                        "<input " + "name=\"" + name + "\"" +
                                    " type=\"hidden\"" +
                                    " value=\"" +
                                    HttpUtility.HtmlEncode(value) +
                                    "\"" +
                        "/>"
                    );
                }
            }

        </script>

    </head>


    <body>

        <p><% WriteDisplay(); %></p>

        <form   action="<% Response.Write(Request.Url.AbsolutePath); %>"
                method="get">

            <br/>
            First name: <input name="first_name"/><br/>
            Last name: <input name="last_name"/><br/>

            <% WritePersistentVars(); %>

            <p><input type="submit" value="Enter"/></p>

        </form>

    </body>

</html>
        

HTTP POST with ASP.NET:

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <title>HTTP POST test</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8"/>

        <script runat="server" language="C#">

            private string prev_first_name;
            private string first_name;
            private string prev_last_name;
            private string last_name;

            private void Page_Load()
            {
                prev_first_name = Request.Form["prev_first_name"];
                first_name = Request.Form["first_name"];
                prev_last_name = Request.Form["prev_last_name"];
                last_name = Request.Form["last_name"];
            }

            private void WriteDisplay()
            {
                Response.Write(
                    Environment.NewLine +
                    "Previous first name entered: \"" +
                    HttpUtility.HtmlEncode(prev_first_name) +
                    "\"<br/>"
                );
                Response.Write(
                    Environment.NewLine +
                    "First name entered: \"" +
                    HttpUtility.HtmlEncode(first_name) +
                    "\"<br/>"
                );

                Response.Write(
                    Environment.NewLine +
                    "Previous last name entered: \"" +
                    HttpUtility.HtmlEncode(prev_last_name) +
                    "\"<br/>"
                );
                Response.Write(
                    Environment.NewLine +
                    "Last name entered: \"" +
                    HttpUtility.HtmlEncode(last_name) +
                    "\"<br/>"
                );
            }

            private void WritePersistentVars()
            {
                WriteHiddenFormVar("prev_first_name", first_name);
                WriteHiddenFormVar("prev_last_name", last_name);
            }

            private void WriteHiddenFormVar(string name, string value)
            {
                if(value != null)
                {
                    Response.Write(
                        Environment.NewLine +
                        "<input " + "name=\"" + name + "\"" +
                                    " type=\"hidden\"" +
                                    " value=\"" +
                                    HttpUtility.HtmlEncode(value) +
                                    "\"" +
                        "/>"
                    );
                }
            }

        </script>

    </head>


    <body>

        <p><% WriteDisplay(); %></p>

        <form   action="<% Response.Write(Request.Url.AbsolutePath); %>"
                method="post">

            <br/>
            First name: <input name="first_name"/><br/>
            Last name: <input name="last_name"/><br/>

            <% WritePersistentVars(); %>

            <p><input type="submit" value="Enter"/></p>

        </form>

    </body>

</html>
        

Using the code

To use this code: