Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Creating Forms in ASP.NET MVC 5

0.00/5 (No votes)
13 Feb 2016 2  
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:

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)

<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:

[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:

@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:

[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

@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:

[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:

<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

<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

[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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here