Lesson Weekend

In this lesson, we'll learn how to add forms to our virtual postcard application so anyone can create a custom postcard for their friends.

Integrating Forms


Adding a New Route

First, we'll add a new Form() route to contain our form:

FriendLetter/Controllers/HomeController.cs
using Microsoft.AspNetCore.Mvc;
using FriendLetter.Models;

namespace FriendLetter.Controllers
{
  public class HomeController : Controller
  {

    ...

    [Route("/form")]
    public ActionResult Form() { return View(); }

  }
}

When we navigate to localhost:5000/form, the code in this route will execute.

Creating a Form View

In our Views/Home directory, we'll create a file called Form.cshtml and add the following:

FriendLetter/Views/Home/Form.cshtml
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
    <title>Create a Custom Postcard!</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  </head>
  <body>
    <h1>Fill in your name and your friend's name to create your custom postcard!</h1>
    <form action="/postcard" method="post">
     <label for="sender">Sender's Name</label>
     <input id="sender" name="sender" type="text">
     <label for="recipient">Recipient's Name</label>
     <input id="recipient" name="recipient" type="text">
     <button type="submit">Go!</button>
    </form>
  </body>
</html>

This form looks fairly similar to ones we've worked with in the past but there are some key differences.

  • Notice the <form> tag includes action="/postcard". This tells ASP.NET Core MVC where to submit info provided through this form. This attribute must be set to the path of another route in our controller. That means if we use a route decorator, it will be set to the path we've specified in the decorator. We'll create a "/postcard" route soon.

  • We create a <label> and <input> for each piece of info the form collects. <input>s must have 3 attributes: name, id, and type.

    • The id can be anything as long as it's unique on this page. Generally, the value will be the same for both name and id.
    • The <input> tag has many different possible values for the type attribute. Examples include dates, colors, and numbers. This one is set to "text".
  • The <label> tag provides the text to display next to the input box. It takes one attribute called for, which should match the id attribute of the corresponding <input> tag. For example, the <input> tag with attribute id="recipient" should have a <label> tag with the attribute for="recipient".

  • The <button> tag creates the button that submits the form. It has one attribute called type. This attribute must be set to "submit". Otherwise, the form won't work correctly.

Dynamically Rendering Form Data


Now that we have a form to submit the data, let's add another route. The page will look like our previous friend letter in Letter.cshtml, but this one will insert custom names gathered from our form.

View

Let's create a Postcard.cshtml view with the following code:

FriendLetter/Views/Home/Postcard.cshtml
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
    <title>A Postcard For You!</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  </head>
  <body>
    <h1>Hello From Afar</h1>
    <p>Dear @Model.Recipient,</p>
    <p>How are you? I hope that you are having a nice weekend. I'm vacationing in the Iceland while I learn programming!</p>
    <p>@Model.Recipient, you would not believe how cold it is here. I should have gone to Hawaii instead.</p>
    <p>But I like programming a lot, so I've got that going for me.</p>
    <p>Looking forward to seeing you soon. I'll bring you back a souvenir.</p>
    <p>Cheers,</p>
    <p>Travel Enthusiast @Model.Sender</p>
  </body>
</html>

Route

Now let's add the code to retrieve the user's form input and insert it into our Postcard.cshtml view. We'll create a new route with a /postcard route decorator to handle this, because the path must match the form's action attribute. When they match, .NET will automatically execute the code in this route when the form is submitted.

Our new route will look like this:

FriendLetter/Controllers/HomeController.cs
...

[Route("/postcard")]
public ActionResult Postcard(string recipient, string sender)
{
  LetterVariable myLetterVariable = new LetterVariable();
  myLetterVariable.Recipient = recipient;
  myLetterVariable.Sender = sender;
  return View(myLetterVariable);
}

...

Here we create a new Postcard() route. This time, the route's method takes arguments: a string for both recipient and sender.

  • Because we told our <form> in Form.cshtml to have an action="/postcard", the route matching the /postcard path is automatically invoked. That's our Postcard() route.

  • Our form has two <input>s, one with a name="sender" attribute and another with a name="recipient" attribute. These are the parameters we pass into the route method.

  • This route can automatically access those values via the parameters we pass into the Postcard() route method.

Note that our application is looking for name attributes, not the id or anything else. These must match the parameters we pass into the route method. This must be an exact match or it will not work.

If we launch the application and visit localhost:5000/form, we can submit our form and then go to the /postcard path to see a letter with custom sender and recipient names from our form.


Example GitHub Repo for Friend Letter

Sample Form

We add forms to a route like this:

[Route("/form")]
public ActionResult Form() { return View(); }

A form generally looks something like this:

FriendLetter/Views/Home/Form.cshtml
<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
    <title>Create a Custom Postcard!</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
  </head>
  <body>
    <h1>Fill in your name and your friend's name to create your custom postcard!</h1>
    <form action="/postcard" method="post">
     <label for="sender">Sender's Name</label>
     <input id="sender" name="sender" type="text">
     <label for="recipient">Recipient's Name</label>
     <input id="recipient" name="recipient" type="text">
     <button type="submit">Go!</button>
    </form>
  </body>
</html>

Forms have a <form> tag with an action and method This tells ASP.NET Core MVC where to submit info provided through this form. This attribute must be set to the path of another route in our controller.

Lesson 16 of 38
Last updated more than 3 months ago.