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.
First, we'll add a new Form()
route to contain our form:
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.
In our Views/Home
directory, we'll create a file called Form.cshtml
and add the following:
<!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
.
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
.<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.
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.
Let's create a Postcard.cshtml
view with the following code:
<!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>
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:
...
[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.
We add forms to a route like this:
[Route("/form")]
public ActionResult Form() { return View(); }
A form generally looks something like this:
<!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.