Razor Forms
Already we have seen that templates allow us to build generic forms. Using templates, you can reuse the structure by rendering the same form, but with different labels and data. Thus, a single form can serve different purposes, saving you extra effort.
Whenever possible, reuse existing templates!
Starting a New Project: Coding Events
You will build a new project so you can practice with templates and forms. If you have not done so, commit and push any unsaved work from your HelloASPDotNET
project.
Your new project will keep track of some coding events, such as meetups and conferences. To get started, follow the steps
you took to create HelloASPDotNET
, but call the project CodingEvents
.
CodingEvents
Setup
In the
Controllers
directory, create a new controller namedEventsController
.In the new controller, create an
Index
action method forGET
requests.Within the action method, create an empty
List
and add a few event names to it.Example13 14 15 16 17 18 19 20
[HttpGet] public IActionResult Index() { List<string> Events = new List<string>(); //Add some events to the List //...code continues }
Add the
List
toViewBag
. Then return the corresponding view.Example13 14 15 16 17 18 19
[HttpGet] public IActionResult Index() { //...code continues ViewBag.events = Events; return View(); }
Within the
Views
directory, create a new directory named Events. Within this directory, create a new view namedIndex.cshtml
.Within the new template, loop over the
List
and display the name of each event.Example8 9 10 11 12 13
<ul> @foreach (string e in ViewBag.events) { <li>@e</li> } </ul>
Create and Render a Form
A Razor form can be made simply with a template that includes a <form>
element. The method for the form should be of type post
.
|
|
You can include as many inputs as you need in the form, and these can be of different types (e.g. text, email, checkbox, etc.). However, each different piece of data you want to collect needs to have a unique name
attribute.
To render the form in the view, add a method to the controller with an [HttpGet]
annotation.
|
|
If the action
attribute in the <form>
tag leads to the same route as the form is being rendered at, you do not have to include an action
attribute.
Create Add
Method and View to CodingEvents
Create a new View for the
EventsController
calledAdd
.Inside the
Add
view, create a form that takes oneinput
oftype
text, and has aname
of “name”. Create a secondinput
oftype
“submit” and with avalue
“Add Event”.Example1 2 3 4
<form method="post"> <input name="name" type="text" /> <input type="submit" value="Add Event" /> </form>
In the
EventsController
, create a new action method calledAdd
.Example1 2 3 4 5
[HttpGet] public IActionResult Add() { return View(); }
Handling Form Submission
In this application, we are storing the name of events inside a list. The Add
view contains a form to capture events names, but the Add
method only renders the form. It does not process the data.
To process a form after the user clicks the Submit button, you need to add a method to the controller using the [HttpPost]
annotation. This method also needs a way to handle any data it captures.
The NewEvent
Action Method
In CodingEvents
let’s create a new action method called NewEvent
which will handle the data provided by a user. In this app, we are asking a user to provide a name of an event related to coding. After a user submits the form, the ideal outcome would be to see and updated list containing that new item. We need to return something other than a View
for this.
We can Redirect
the path back to the /Events
view to see the new list item.
We could start creating our NewEvent
method like this:
|
|
Line 33: For each piece of data that needs to be retrieved from the form, declare a parameter of the appropriate type.
The method code performs any data manipulation required after the information gets submitted.
Line 36: We may want to send the user to a different page after they successfully submit a form. Instead of re-rendering the form, we want to use
Redirect()
to redirect the user to a different template.
Anchor Tags and Form Submission
Now that we have a form and can handle the form submission, we want to create a link to the form to add an event in our Index
template. This way, after reviewing the list of events, users can click on the link to the form and add an event. To do this, we use anchor tag helpers
. The basic format is as follows:
<a asp-controller="ControllerName" asp-action="ViewName">Text Here</a>
Then when we build our application, the generated HTML of the page will look like:
<a href="/ControllerName/ViewName">Text Here</a>
Try it in CodingEvents
In your
EventsController
create an action method calledNewEvent
that redirects users to the"/Events"
. This method should be a post request, and use the following route:"/Events/Add"
.Example31 32 33 34 35 36 37
[HttpPost] public IActionResult NewEvent(string name) { // Any additional method code here return Redirect("/Events"); }
The
NewEvent
needs to add the any provided arguments to theEvents
list.Example31 32 33 34 35 36 37
[HttpPost] public IActionResult NewEvent(string name) { Events.Add(name); return Redirect("/Events"); }
You may have an error with the
Events.Add(name);
in theNewEvent
action method. It cannot reach theEvents
List contained in theIndex
method. Remove the list from theIndex
method. Instead declare theEvents
list above theIndex
method. Make sure that it has the correct access modifiers that provide access to elements shared within theEventsController
.Example13
static private List<string> Events = new List<string>();
How can users add a New Event to the list? In the
Events/Index
view, add an anchor tag where theasp-controller
is set to theEvents
controller and theasp-action
is set to theAdd
action method. Make sure a user knows this anchor tag’s functionality.Example4 5 6 7
@* Inside Events/Index View *@ <p> <a asp-controller="Events" asp-action="Add">Add Event</a> </p>
If there are no events in our list, how could we encourage users to add one or more? Add a conditional to the
Index
view that creates a message only if theEvents
list is empty.Example13 14 15 16
@if(ViewBag.events.Count == 0) { <p>No events yet!</p> }
Users can now click on the link on our page at localhost:5001/Events
and are directed to the form to add an event. Once they hit the button to submit the form, the data is passed to the NewEvent()
method, the user’s event is added to the Events
list, and the application redirects back to localhost:5001/Events
where an updated Events
list is displayed.
You can compare your code to the chapter’s walkthrough .