Model Binding using FromForm in ASP.NET Core MVC

Model Binding using FromForm in ASP.NET Core MVC:

In this article, I will discuss How to Use FromForm to Perform Model Binding in an ASP.NET Core MVC Application with Examples. Please read our previous article discussing the basic concepts of Model Binding in ASP.NET Core MVC.

Model Binding using FromForm in ASP.NET Core MVC

Model Binding in ASP.NET Core MVC simplifies handling HTTP requests by automatically mapping data from the request to action method parameters. When we use the FromForm attribute in ASP.NET Core MVC Controller action, we instruct the MVC Framework to bind input values from the HTTP POST or PUT request form (i.e., form fields) to a model or method parameter.

This is useful in scenarios where you deal with forms that submit data to the server. This is common in ASP.NET Core MVC applications, where we created HTML forms that use the POST or PUT method to submit data to the server. If you go to the definition of the FromFormAttribute class, you will see the following.

How to Use FromForm to Perform Model Binding in ASP.NET Core MVC with Examples

This attribute belongs to Microsoft.AspNetCore.Mvc namespace, which automatically maps HTTP request data to action method parameters. The FromFormAttribute targets data sent via HTML form submissions, particularly those submitted using POST and PUT methods where the content type is typically application/x-www-form-urlencoded or multipart/form-data (for forms that include file uploads).

  • BindingSource Property: The BindingSource property of the FromFormAttribute specifies where the data should be bound from. Each model binding attribute in ASP.NET Core has a corresponding BindingSource that indicates the source of the data it is meant to handle. For FromFormAttribute, this is set to BindingSource.Form, which tells the model binder to look for data in the form body of the HTTP request.
  • Name Property: This is particularly useful in cases where the form fields submitted by the client do not match the parameter names in the method signature. Here, using the Name Property of the FromForm Attribute, we can specify the name that matches the input form field name.
Example to Understand FromForm Attribute in ASP.NET Core MVC

Let us understand this with an example. First, create a class representing the form data. For example, if we have a form for user registration, we need to create a model with properties such as ID, Name, Email, Password, and Mobile. So, first, create a class file named User.cs within the Models folder and then copy and paste the following code into it. 

namespace ModelBindingDemo.Models
{
    public class User
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public string? Email { get; set; }
        public string? Password { get; set; }
        public string? Mobile { get; set; }
    }
}
Create an Action Method:

Next, in our controller, we need to define an action method to handle the form submission. Use the FromForm attribute to specify that the action method should accept data from the form. So, create a UsersController controller within the Controllers folder and copy and paste the following code. The Create action method, decorated with the HttpPost attribute, will handle the form POST request.

using Microsoft.AspNetCore.Mvc;
using ModelBindingDemo.Models;

namespace ModelBindingDemo.Controllers
{
    public class UsersController : Controller
    {
        [HttpGet("users/create")]
        public IActionResult Create()
        {
            // Return the view that has the form to create a user
            return View();  
        }

        [HttpPost("users/create")]
        public IActionResult Create([FromForm] User user)
        {
            if (!ModelState.IsValid)
            {
                // Return the form view with the posted data and validation messages
                return View(user); 
            }

            // Process the Model, i.e., Save user to database
            // Redirect to another action after successful operation
            return RedirectToAction("SuccessAction"); 
        }

        public string SuccessAction()
        {
            return "User Created Successfully";
        }
    }
}

In the above example, when the form is submitted, the data from the form body is automatically bound to the User object of the Create action method (Create method, which is decorated with HttpPost Attribute) using the FromForm attribute. The FromForm attribute maps the posted form data to the User object.

Create a Form in a View:

Next, we need to create a view, and inside the view, we need to create a form using which the user submits his data. The name attributes of the form inputs must match the properties of the model. So, create the Create.cshtml view within the Views/Users directory. Once you create the Create.cshtml view, copy and paste the following code.

@model User
@{
    ViewData["Title"] = "Create";
}

<h1>User Registration Form</h1>

<form method="post" asp-controller="Users" asp-action="create" class="p-4">
    <div class="mb-3">
        <label for="Name" class="form-label">Name</label>
        <input asp-for="Name" class="form-control" placeholder="Enter Your Name" />
    </div>
    <div class="mb-3">
        <label for="Email" class="form-label">Email</label>
        <input asp-for="Email" class="form-control" placeholder="Enter Your Email" />
    </div>
    <div class="mb-3">
        <label for="Password" class="form-label">Password</label>
        <input asp-for="Password" type="password" class="form-control" placeholder="Enter Your Password" />
    </div>
    <div class="mb-3">
        <label for="Mobile" class="form-label">Mobile</label>
        <input asp-for="Mobile" type="Mobile" class="form-control" placeholder="Enter Your Mobile Number" />
    </div>
    <button type="submit" class="btn btn-primary">Register</button>
</form>

Now, run the application and create a user by visiting the /users/create URL. You will see the respective view to create the user, as expected. Provide the details in the view and click the Submit button, as shown in the image below.

Model Binding using FromForm in ASP.NET Core MVC

Using Primitive Type with FromForm Attribute:

Instead of using the Complex type, we can also use the primitive data type along with the FromForm attribute. To better understand, please modify the UsersController as follows.

using Microsoft.AspNetCore.Mvc;
namespace ModelBindingDemo.Controllers
{
    public class UsersController : Controller
    {
        [HttpGet("users/create")]
        public IActionResult Create()
        {
            // Return the view that has the form to create a user
            return View();
        }

        [HttpPost("users/create")]
        public IActionResult Create([FromForm] string Name, [FromForm] string Email, [FromForm] string Password, [FromForm] string Mobile)
        {
            // Validate the Data 
            // Save user to database

            // Redirect to another action after successful operation
            return RedirectToAction("SuccessAction");
        }

        public string SuccessAction()
        {
            return "User Created Successfully";
        }
    }
}
How Does Model Binding Work with FromForm Attribute in ASP.NET Core?

When a user submits a form on a web page, the browser packages the data entered into the form fields and sends it to the server as part of the request body. The data can be encoded as application/x-www-form-urlencoded where the form data is encoded as key-value pairs (similar to query strings), or multipart/form-data when the form includes file uploads. The following is a detailed step-by-step process of how model binding works with the FromForm attribute:

  • Step 1: Identify the Source: The model binder recognizes that the binding source is the request body’s form data due to the FromForm attribute.
  • Step 2: Match Form Fields to Parameters: It then tries to match the names of the form field fields with the names of the action method parameters. If the names match, it binds the values to those parameters. If a Name property is set in the FromForm attribute, that name will be used to look up form data instead of the parameter name.
  • Step 3: Conversion and Binding: The model binder converts the form data (which is initially in string format) to the types of the respective action method parameters. ASP.NET Core has built-in type converters to handle this for most common data types, including custom complex types.
  • Step 4: Handling Errors and Validation: If errors occur during binding (like type mismatches) or validation fails based on data annotations or custom validators, the model binder updates the ModelState with these errors. Then, we can check the ModelState.IsValid to determine if there were issues with the incoming data.
Using the Name Property of FromFormAttribute:

Suppose you have a form field named Email, but in your model or method, you want to bind it to a property or parameter named UserEmail. Again, we want to map the Name form field with the UserName parameter. In this case, we can use the Name property of the FromForm Attribute to map these correctly. For a better understanding, please modify the UsersController as follows:

using Microsoft.AspNetCore.Mvc;
namespace ModelBindingDemo.Controllers
{
    public class UsersController : Controller
    {
        [HttpGet("users/create")]
        public IActionResult Create()
        {
            // Return the view that has the form to create a user
            return View();
        }

        [HttpPost("users/create")]
        public IActionResult Create([FromForm(Name ="Name")] string UserName, [FromForm(Name ="Email")] string UserEmail, [FromForm] string Password, [FromForm] string Mobile)
        {
            // Validate the Data 
            // Save user to database

            // Redirect to another action after successful operation
            return RedirectToAction("SuccessAction");
        }

        public string SuccessAction()
        {
            return "User Created Successfully";
        }
    }
}

Now, with the above changes in place, run the application, and it should work as expected.

When Should We Use FromForm Attribute in ASP.NET Core MVC?

In ASP.NET Core MVC, the FromForm attribute indicates that a parameter should be bound from the form data in the request body. The following are some scenarios where we can use the FromForm attribute:

Traditional HTML Forms:

One of the most common use cases for FromForm is when dealing with traditional HTML forms. 

<form method="post" action="/submit">
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" value="Submit" />
</form>

When the form is submitted, the data is sent in the request body. The FromForm attribute binds this data to the action method’s parameters.

File Uploads:

When handling file uploads with a form using enctype=”multipart/form-data”, the FromForm attribute is used to bind uploaded files and any additional form fields.

<form method="post" action="/upload" enctype="multipart/form-data">
    <input type="file" name="uploadedFile" />
    <input type="text" name="description" />
    <input type="submit" value="Upload" />
</form>

In the corresponding action method, you might have:

[HttpPost("/upload")]
public IActionResult Upload([FromForm] IFormFile uploadedFile, [FromForm] string description)
{
    // Handle file and description
}
When Not to Use FromForm Attribute?

If we are building an API, i.e., Restful Services, that will be consumed by other clients, such as mobile apps or frontend frameworks like React, Angular, or Vue.js, where we generally work with JSON payloads rather than form data, we should use FromBody instead of FromForm Attribute.

In the next article, I will discuss Using FromQuery to Perform Model Binding in ASP.NET Core MVC with Examples. In this article, I explain How to use FromForm to Perform Model Binding in ASP.NET Core MVC with Examples. I hope you enjoy this FromForm in ASP.NET Core MVC article.

Leave a Reply

Your email address will not be published. Required fields are marked *