Building ASP.NET MVC Forms with Razor (ASP.NET MVC Foundations Series)

[Update: Want to watch this as a screencast rather than article?]

In this ASP.NET MVC Foundations article, we’re going to look at building an ASP.NET MVC page which allows users to create and edit objects in our domain. We’ll cover just the basics of using HTML helpers to map model properties to our HTML form and Model Binding to convert our HTML form back into our rich domain object.

We’ll start with a very basic store website (downloads here: BasicMvcForms_starter.zip and BasicMvcForms_final.zip)which has a database and some basic products already listed:

Notice that we have five products. There links to edit and create products. Currently, they don’t do much:

First we’ll need to add action methods. That’s easy enough. Here’s the create code:

And similarly, the edit code:

Now that we have action methods for edit and create, we’ll need the corresponding views. Use the Visual Studio tooling to create two empty views as follows:

In the resulting dialog, choose strongly-typed with Product and an empty view without referencing the scripts (we do this globally already). In practice, you might choose “edit” and “create” to help jump-start the Razor code. In this example, we’ll do that from scratch so empty is what we want.

Now our links to edit and create products work. However they don’t have any content in their views. We’ll use the HTML Helper methods to convert our product into forms ready for the editing.

It all starts with Html.BeginForm(). We’ll define a form using this MVC convention and helper method as follows:

Next, we use the Model property of the view and the HTML helper methods to define the input fields. Note that we’re using Html.TextBoxFor() and Html.LabelFor() to create the fields. Our Featured property is a Boolean, so we’ll use Html.CheckBoxFor() on that one.

Once we flesh out the other properties, we’ll be finished with the create view. And it turns out the edit view is identical. There are tricks to share them across actions (e.g. PartialViews) but for our simple example, we’ll just copy / paste between the two views.

Last thing we need is a submit button to submit the form.

Now we should have a nice usable form to create products (or edit them if you copy & pasted that view). Here’s the edit view:

The final step is to capture the form data on the controller methods and update the database. This is where it gets interesting.

We will define a second method for each action (create & edit) which accept the post. We do not want our “show the form to start editing” code to mix with the “save the data and move on” code. We’ll achieve this separation using two attributes HttpGet & HttpPost.

Notice the original Create method has the GET attribute. This displays the form to begin creating a product. The second one is more interesting. It adds the product to the DB and returns to the product list. It also only accepts POST requests. Notice that it accepts a Product parameter which is populated using model binding by ASP.NET MVC.

Learn this pattern! It’s super common in MVC. I’ll call it the Get+Post+Redirect pattern.

  1. HttpGet method shows form, returns View().
  2. HttpPost method accepts the model (which is populated using model binding)
  3. HttpPost method then updates the data and redirects to a new view.

Edit is similar. Often, websites use AutoMapper to do the manual copy / update you see here.

Now we have a fully functioning store (albeit a simple one). One glaring omission is validation. We’ll cover that in another post.

Conclusion

To wrap up, we took a basic MVC website and went through these steps:

  •  Added edit and create methods
  • The new methods returned the correct model
  • Added strongly-typed views for each method
  • Used Html.BeginForm() and related Html.XXXXFor() methods to build out the form
  • Added a submit button
  • Implemented the Get+Post+Redirect pattern in edit and create.
  • Take the rest of the day off. :)

Good luck with your websites and happy POSTing.

– Cheers
@mkennedy

19 comments

Submit a comment