Click here to Skip to main content
15,881,856 members
Articles / Web Development / HTML

Creating Forms in ASP.NET MVC 5

Rate me:
Please Sign up or sign in to vote.
4.96/5 (26 votes)
13 Feb 2016CPOL7 min read 227.2K   30   4
We examine four ways to create forms in ASP.NET MVC 5: weakly typed synchronous forms, strongly typed synchronous forms, strongly typed asynchronous forms, and using jQuery AJAX to post form data.

Introduction

When I first started developing web applications with ASP.NET MVC, I struggled to learn how to create forms. Although my forms worked (thank goodness for <Ctrl-c Ctrl-v>), they were far from scalable and I wasn’t sure how they worked. The purpose of this introductory article is to help guide the beginner in creating forms. We will discuss four types of forms:

  • weakly typed synchronous forms
  • strongly typed synchronous forms
  • strongly typed AJAX forms
  • use jQuery with AJAX to post form data

To enhance your learning experience, you can fork the four form examples and experiment with them as you read along from https://github.com/NanoBreeze/CodeProject-Creating-Forms-in-ASP.NET-MVC-5.

If you already have experience creating forms, you can check out the Further Reading section for more comprehensive details on forms.

Background

Each form contains three basic elements: a <form> element, <input> elements (which the user can type to), and some type of a submit button.

In our example, each of our forms contains a checkbox, a textbox for strings, and a textbox for numbers because these are some of the most frequently used <input>s.

Setup

We create a new controller, view, and model (which is really a class that contains auto-implemented properties. The model will be used by the strongly-typed form examples). Let’s name the controller “Form” (this will create a new file called “FormController.cs” in the Controllers folder) and add a view for its Index action method.

Next, let’s make a class “FormData.cs” in the Model folder (you can actually place the class anywhere but by convention, we place it in the Model folder) whose properties would store the user's inputs:

C#
namespace LearningForms.Models
{
    public class FormData
    {
        public string TextBoxStringData { get; set; }

        public int TextBoxIntData { get; set; }

        public bool CheckboxData { get; set; }
    }
}

Weakly Typed Synchronous Forms

This is the quickest way to post a form. Each <input>'s name must match one parameter’s name in the method the form is posted to. The characters or digits that users type into <input> elements become part of the <input>’s value attribute and since <input> values are passed from client to server by matching names, make sure there are no typos.

Client (Index.cshtml under ~/Views/Forms)

HTML
<form action="/Form/FormOne" method="post">
    <input type="text" name="textBoxStringData" />
    <input type="checkbox" name="checkboxData" />
    <input type="number" name="textBoxIntData" />

    <input type="submit" value="Submit weakly typed form" />
</form>
Notes
  • The <form> element. This is the parent element for all form-related elements, including <input>s.
    • action indicates the method the form is posted to (aka, the method that will receive the value of the <input> element, which the user has typed in before submitting the form).
    • method specifies the HTTP verb we’re using. Setting method="post" ensures that the information in this form can only be sent to the server from a form or from JavaScript and not from the URL. You can learn more about HTTP verbs here.
  • The <input> elements. Users type data into the input elements.
    • type indicates the type of data the input accepts. E.g., textbox, checkbox, radio button, submit button
    • name is very important and it must match the parameter names of the method the form is posted to

Server

Make a new method in FormController.cs called FormOne that accepts parameters whose names are identical to the names of the <input> elements. Let’s also provide the method a [HttpPost] attribute:

C#
[HttpPost]
public void FormOne(string textBoxStringData, int textBoxIntData, string checkboxData)
{
    //Do something
}
Notes
  • Parameter names. These must be identical to <input> names. If they are different, <input> values will not pass to FormOne.
  • [HttpPost] attribute. Ensures that the information in this form can only be sent to the server from a <form> or from JavaScript and not from the URL. This is why we had set method=”post” in the <form> element
  • Checkbox. If the checkbox were checked, checkboxData’s value would be "on". If it were unchecked, its value would be null. You might have been surprised to see we set checkboxData ‘s data type to be a string instead of a bool. This is because if checkboxData were bool type, the system would throw an exception and if checkboxData were a bool? type, its value would always be null independent of whether it were checked or unchecked.

Next Steps

After the user submits a form, the page usually redirects to another page. We can change the return type of FormOne to ActionResult and return a RedirectToAction(“ActionName”); to redirect the user to another page. You can check this article’s source code for an example.

Strongly Typed Synchronous Forms

In a strongly typed form, we pass from the client to the server an object (the model) whose properties contain the <input> values instead of passing many primitives. An advantage of using strongly typed forms is easier maintainability. Unlike weakly typed forms, typos are unlikely to happen. Also, the method the form is posted to has fewer parameters.

Client

The client uses HTML Helpers to represent the <form> and <input> elements. We also include our model object at the top of the file:

HTML
@using (Html.BeginForm("FormTwo", "Form", FormMethod.Post))
{
    @Html.TextBoxFor(m => m.TextBoxStringData)
    @Html.CheckBoxFor(model => model.CheckboxData)
    @Html.TextBoxFor(model => model.TextBoxIntData)

    <input type="submit" value="Submit strongly type synchronous form" />
}
Notes
  • @model. The general syntax is @model namespace.className. Here, FormData is the object that is passed from the client to server. To assign <input> values to FormData properties, we use…
  • Html helpers (e.g., Html.BeginForm and @Html.TextBoxFor( m=> m.TextBoxStringData)
    • Html.BeginForm(...). When rendered on a webpage, this actually displays as a <form> element. The first two arguments in BeginForm are the names of the method and
    • @Html.TextBoxFor(m => m.TextBoxStringData). I know what you’re thinking: what’s up with the argument? Yepp, those were my thoughts as well. The argument is a lambda expression and it basically means that m is the instance of our model object (Forms.Models.FormData) and the <input>’s value is stored in Forms.Models.FormData.TextBoxStringData

Server

Make a new method in FormController.cs called FormTwo:

C#
[HttpPost]
public void FormTwo(Models.FormData formData)
{
    //Do something with formData
}
Notes
  • FormTwo has a single parameter whose type is our model object! This can be more convenient than using weakly typed forms because if we later decide to add another <input> to our <form>, we simply add another property to FormData and an Html helper to Html.BeginForm, without changing the parameters in FormTwo.

Strongly Typed Asynchronous Forms

We combine the advantages of strongly typed form with AJAX. This is similar to a strongly typed synchronous form

Client

HTML
@using (Ajax.BeginForm("FormThree", "Form", 
	new AjaxOptions { LoadingElementId = "loader", OnSuccess = "onSuccess" }))
{
    @Html.TextBoxFor(m => m.TextBoxStringData)
    @Html.CheckBoxFor(m => m.CheckboxData)
    @Html.TextBoxFor(m => m.TextBoxIntData)

    <input type="submit" value="Submit strongly typed asynchronous form" />
}

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
Notes
  • Ajax.BeginForm(…). the first two arguments are the same as in Html.BeginForm. The third argument includes information about our AJAX request, such as which JavaScript function to call after the successful completion of an AJAX post.
  • jQuery scripts. Remember to include jQuery as well as jQuery unobtrusive Ajax, which can be installed by typing in the Package Manager:
Install-Package jQuery.Ajax.Unobtrusive

Make sure that the script containing jQuery is placed above the script containing jQuery unobtrusive ajax.

Server

Same as for strongly typed synchronous forms:

C#
[HttpPost]
public void FormThree(Models.FormData formData)
{
    //Do something with formData
}

Next Steps

We can make a dialog appear while the server is processing the AJAX post.

Add LoadingElementId = "loader" as a property to AjaxOptions.

Then, place somewhere on the same file:

HTML
<div id="loader" style="display:none">
   Loading...
</div>

When the form is submitted and being processed by the server, ‘Loading...” will appear on the screen.

Using jQuery with AJAX to Post Data

We will be using a bit of JavaScript in this example. An advantage of using jQuery to post data is that the data is not restricted only to <input>s. They can also be the text of <p>s or class names of an element.

Client

HTML
<input type="text" id="text" />
<input type="checkbox" id="checkbox" />
<input type="number" id="number" />

<button onclick="submit()">Post with jQuery AJAX</button>

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>

    //submit data with jQuery AJAX
    function submit() {
        var data = {
            TextBoxStringData: $('#text').val(),
            TextBoxIntData: $('#number').val(),
            CheckboxData: $('#checkbox').is(':checked')
        };

        $.post("/Form/FormFour", { formData: data }, 
		function () { alert('Successfully posted to server') });
    }
Notes
  • $.post(…). This performs an AJAX post. The first argument is the path of the method the form posts to; the second argument is the object to post (like a model); and the third is a callback function that executes if the post is successful.
  • Make sure the property of the second argument in $.post(...) is equal to the name of the FormData parameter in the method the form is posted to. In addition, make sure that the data’s property names are identical to FormData’s property names.

Server

C#
[HttpPost]
public void FormFour(Models.FormData formData)
{
    //Do something with formData
}

Further Reading

Thanks for reading! Hopefully, this article helped you gain a greater understanding of creating forms in MVC 5.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Canada Canada
I'm a software developer with experience in infrastructure, back-end, and front-end development. I graduated with a BASc in Computer Engineering from the University of Waterloo in 2019. To learn how my skills may align with your needs, please feel free to send me a message or view my portfolio at: https://lennycheng.com

Comments and Discussions

 
GeneralMy vote of 4 Pin
ovisariesdk4-Jan-17 4:51
ovisariesdk4-Jan-17 4:51 
QuestionStrongly typed asynchronous submissions are sending a blank model. Pin
Daniel Griggs16-Sep-16 10:31
Daniel Griggs16-Sep-16 10:31 
QuestionGreat summary Pin
Chris Maunder14-Feb-16 1:49
cofounderChris Maunder14-Feb-16 1:49 
AnswerRe: Great summary Pin
Lenny Cheng31-Mar-16 9:03
professionalLenny Cheng31-Mar-16 9:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.