cshttp Tutorial - Day 3: Accepting User Input (URL Query Strings & GET Forms)

Back to cshttp Tutorial Main Menu

Day 3: Accepting User Input (URL Query Strings & GET Forms)

In Day 1 and Day 2, our website only sent information from the server to the visitor.

Today, we will teach our web server how to accept input from the visitor so our website becomes truly interactive!

In Day 3, we will:

  1. Learn how URL Query Strings work (for example: /greet?name=Alice).
  2. Add a new /greet route to our router and navigation menu.
  3. Read visitor parameters in C# using Request.QueryString["name"].
  4. Build an interactive HTML <form> so visitors can type their name into a text box and click a button to send it to our C# server.

1. Understanding URL Query Strings

Have you ever searched for something on Google or YouTube and noticed a question mark (?) in the browser's address bar?

https://www.google.com/search?q=csharp
http://localhost:8080/greet?name=Alice

Let's break down the two parts of http://localhost:8080/greet?name=Alice:

PartValueMeaning
Path/greetTells the server which page the visitor wants to open.
Query String?name=AliceSends extra data (a key-value pair) to that page!
  • The ? symbol marks the start of the query string.
  • name is the parameter key (variable name).
  • Alice is the value passed into that parameter.

If you want to pass more than one parameter in a URL, you separate them with an & symbol:

http://localhost:8080/greet?name=Alice&city=Seattle

2. Adding the /greet Page to Our Website

First, let's add a new /greet page to the code we wrote at the end of Day 2.

Step 1: Add /greet to OnRequest()

Inside OnRequest(), add case "/greet": to our switch statement so it calls HandleGreet():

static void OnRequest()
{
    string path = Request.Path.ToLower();

    switch (path)
    {
        case "/":
        case "/home":
            HandleHome();
            break;
        case "/greet":       // <-- NEW: Route /greet to HandleGreet()
            HandleGreet();
            break;
        case "/about":
            HandleAbout();
            break;
        case "/contact":
            HandleContact();
            break;
        default:
            HandleNotFound();
            break;
    }
}

Step 2: Add the "Greet" Link to RenderPage()

Next, add <a href='/greet'>Greet</a> | to our <nav> bar inside RenderPage(). Because RenderPage() is our shared master template, this new link will immediately appear on every page:

static void RenderPage(string title, string bodyContent)
{
    string html = $@"
<html>
    <head>
        <title>{title}</title>
    </head>
    <body>
        <nav>
            <a href='/'>Home</a> | 
            <a href='/greet'>Greet</a> | 
            <a href='/about'>About</a> | 
            <a href='/contact'>Contact</a>
        </nav>
        <hr />
        
        {bodyContent}

        <hr />
        <footer>
            <small>Server Time: {DateTime.Now:yyyy-MM-dd HH:mm:ss}</small>
        </footer>
    </body>
</html>";

    Response.Write(html);
}

3. Reading the Query String in HandleGreet()

Now let's create the HandleGreet() method!

In cshttp, reading a query string parameter from the URL is just one line of code:

string name = Request.QueryString["name"];

Let's see what happens when a visitor opens /greet?name=Alice:

  • Request.QueryString["name"] returns "Alice".

What if a visitor just clicks the Greet link in the navigation menu (/greet) without ?name=... at the end?

  • Request.QueryString["name"] returns null (or an empty string "" if they typed /greet?name=).

Let's write a simple version of HandleGreet() first to see how Request.QueryString["name"] works:

static void HandleGreet()
{
    string name = Request.QueryString["name"];

    string content = $@"
        <h1>Interactive Greeting</h1>
        <h2>Hello, {name}!</h2>";

    RenderPage("Greet", content);
}

4. Handling Missing Input with string.IsNullOrEmpty()

Look closely at the simple HandleGreet() method above. If someone visits http://localhost:8080/greet without providing a name in the URL, {name} is blank, so the page will awkwardly display:

Hello, !

To make our page smarter, we can use C#'s built-in string.IsNullOrEmpty(name) method inside an if / else statement:

  • If name is empty: Show a friendly prompt asking the user to enter their name, along with two quick test links (?name=Alice and ?name=Bob).
  • Else (name is provided): Show the personalized greeting!

Let's update HandleGreet() with this if / else check:

static void HandleGreet()
{
    // 1. Read the "name" parameter from the URL (e.g. /greet?name=Alice)
    string name = Request.QueryString["name"];

    // 2. Decide what message to show using standard C# if/else
    string greetingMessage = "";

    if (string.IsNullOrEmpty(name))
    {
        greetingMessage = "<p>Please enter your name, or try clicking a quick link below!</p>";
    }
    else
    {
        greetingMessage = $"<h2>Hello, {name}! Welcome to C# Web Development!</h2>";
    }

    // 3. Display the greeting message and quick test links
    string content = $@"
        <h1>Interactive Greeting</h1>
        {greetingMessage}

        <p>Test query links directly: 
            <a href='/greet?name=Alice'>Greet Alice</a> | 
            <a href='/greet?name=Bob'>Greet Bob</a>
        </p>";

    RenderPage("Greet", content);
}

Try thinking through how those two links work:

  • Clicking Greet Alice navigates the browser to /greet?name=Alice.
  • Our C# server runs HandleGreet(), sees name is "Alice", and replies with "Hello, Alice! Welcome to C# Web Development!"

5. Adding an Interactive HTML <form>

Clicking pre-made links for Alice and Bob is neat, but what if the visitor wants to type their own name?

In HTML, we use a <form> element to create input boxes and submit buttons:

<form action='/greet' method='get'>
    <label>Your Name:</label>
    <input type='text' name='name' placeholder='Type your name...' />
    <button type='submit'>Say Hello</button>
</form>

How Does This <form> Work?

Let's examine each important piece of this HTML form:

  1. action='/greet':

    Tells the browser which URL path to send the data to when the user clicks the button.

  2. method='get':

    Tells the browser to attach the form's input values directly onto the URL as a Query String (after a ?).

  3. <input type='text' name='name' ... />:

    Creates a text box. Notice name='name'! Whatever attribute value you give to name='...' in HTML becomes the exact parameter key in the URL (?name=...), which matches Request.QueryString["name"] in our C# code!

  4. <button type='submit'>Say Hello</button>:

    When clicked, the browser takes what the user typed into the <input> box (say, Charlie), combines it with action='/greet', and automatically navigates to:

     http://localhost:8080/greet?name=Charlie

Let's add this <form> directly into HandleGreet():

static void HandleGreet()
{
    // 1. Read the "name" parameter from the URL (e.g. /greet?name=Alice)
    string name = Request.QueryString["name"];

    // 2. Decide what message to show using standard C# if/else
    string greetingMessage = "";

    if (string.IsNullOrEmpty(name))
    {
        greetingMessage = "<p>Please enter your name below, or try clicking a quick link!</p>";
    }
    else
    {
        greetingMessage = $"<h2>Hello, {name}! Welcome to C# Web Development!</h2>";
    }

    // 3. Render both the message AND the form so they can try again
    string content = $@"
        <h1>Interactive Greeting</h1>
        {greetingMessage}

        <form action='/greet' method='get'>
            <label>Your Name:</label>
            <input type='text' name='name' placeholder='Type your name...' />
            <button type='submit'>Say Hello</button>
        </form>

        <p>Or test query links directly: 
            <a href='/greet?name=Alice'>Greet Alice</a> | 
            <a href='/greet?name=Bob'>Greet Bob</a>
        </p>";

    RenderPage("Greet", content);
}

6. Complete Code for Day 3

Here is the complete Program.cs with everything we built today:

using System;
using cshttp;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            WebApp.Run(8080, OnRequest);
        }

        static void OnRequest()
        {
            string path = Request.Path.ToLower();

            switch (path)
            {
                case "/":
                case "/home":
                    HandleHome();
                    break;
                case "/greet":
                    HandleGreet();
                    break;
                case "/about":
                    HandleAbout();
                    break;
                case "/contact":
                    HandleContact();
                    break;
                default:
                    HandleNotFound();
                    break;
            }
        }

        static void RenderPage(string title, string bodyContent)
        {
            string html = $@"
<html>
    <head>
        <title>{title}</title>
    </head>
    <body>
        <nav>
            <a href='/'>Home</a> | 
            <a href='/greet'>Greet</a> | 
            <a href='/about'>About</a> | 
            <a href='/contact'>Contact</a>
        </nav>
        <hr />
        
        {bodyContent}

        <hr />
        <footer>
            <small>Server Time: {DateTime.Now:yyyy-MM-dd HH:mm:ss}</small>
        </footer>
    </body>
</html>";

            Response.Write(html);
        }

        static void HandleGreet()
        {
            // 1. Read the "name" parameter from the URL (e.g. /greet?name=Alice)
            string name = Request.QueryString["name"];

            // 2. Decide what message to show using standard C# if/else
            string greetingMessage = "";

            if (string.IsNullOrEmpty(name))
            {
                greetingMessage = "<p>Please enter your name below, or try clicking a quick link!</p>";
            }
            else
            {
                greetingMessage = $"<h2>Hello, {name}! Welcome to C# Web Development!</h2>";
            }

            // 3. Render both the message AND the form so they can try again
            string content = $@"
                <h1>Interactive Greeting</h1>
                {greetingMessage}

                <form action='/greet' method='get'>
                    <label>Your Name:</label>
                    <input type='text' name='name' placeholder='Type your name...' />
                    <button type='submit'>Say Hello</button>
                </form>

                <p>Or test query links directly: 
                    <a href='/greet?name=Alice'>Greet Alice</a> | 
                    <a href='/greet?name=Bob'>Greet Bob</a>
                </p>";

            RenderPage("Greet", content);
        }

        static void HandleHome()
        {
            string content = @"
                <h1>Welcome cshttp!</h1>
                <p>Click on <a href='/greet'>Greet</a> in the menu to test user input!</p>";

            RenderPage("Home", content);
        }

        static void HandleAbout()
        {
            string content = @"
                <h1>About Us</h1>
                <p>It's Me!</p>";

            RenderPage("About Us", content);
        }

        static void HandleContact()
        {
            string content = @"
                <h1>Contact</h1>
                <p>Email us at [email protected]</p>";

            RenderPage("Contact", content);
        }

        static void HandleNotFound()
        {
            Response.StatusCode = 404;
            string content = @"
                <h1>404 Not Found</h1>
                <p>The page that you are looking for does not exist.</p>";

            RenderPage("404 Not Found", content);
        }
    }
}

7. Test It in Your Browser

  1. Run the application (dotnet run or press Start in Visual Studio).
  2. Open your browser and visit http://localhost:8080/greet.
  3. Click Greet Alice or Greet Bob and look at the browser's address bar (http://localhost:8080/greet?name=Alice).
  4. Now type your own name into the text box and click Say Hello.
  5. Notice how the browser automatically builds the URL http://localhost:8080/greet?name=YourName, and your C# server reads it and personalizes the page for you!

In Day 4, we will upgrade our Contact page to use HTTP POST so visitors can submit longer messages and multi-field forms without cluttering the browser's URL bar.