Model Binding using FromForm in ASP.NET Core MVC

Model Binding using FromForm in ASP.NET Core MVC:

I will discuss How to Use FromForm to Perform Model Binding in ASP.NET Core MVC with Examples in this article. 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

The FromForm attribute in ASP.NET Core MVC is used to specify that a parameter should be bound using data from the form body of the HTTP request. This is common for traditional HTML forms that use the POST method to submit data to the server. If you go to the definition of the FromForm class, you will see the following.

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

The FromForm Attribute specifies that a parameter or property should be bound using form data in the request body.

When you have a form in an HTML page, the browser sends the form data as application/x-www-form-urlencoded MIME type. The FromForm attribute instructs the model binder to fetch the data from the form body of the request and try to bind it to the specified action method parameters or model properties.

Example to Understand FromForm in ASP.NET Core MVC

So, first, create a class file with the name User.cs within the Models folder and then copy and paste the following code into it. This is a simple model that represents a user.

namespace ModelBindingDemo.Models
{
    public class User
    {
        public int Id { get; set; }
        public string? Name { get; set; }
        public int Age { get; set; }
        public string? Mobile { get; set; }
    }
}

Next, create a controller named UsersController and copy and paste the following code into it. The controller that handles the form POST. In this case, the Create method, decorated with the HttpPost attribute, handles the form POST.

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); 
            }

            // Save user to database or other operations...
            // 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 in the Create action method using the FromForm attribute. The FromForm attribute will be responsible for mapping the posted form data to the User object.

Next, create the Create.cshtml view for the Create action method of the Users controller. Once you create the Create.cshtml view, copy and paste the following code.

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

<h1>Create User Form</h1>
<form method="post" asp-controller="Users" asp-action="create">
    <label>Name:</label>
    <input asp-for="Name" placeholder="Enter Your Name" />
    <br />

    <label>Age:</label>
    <input asp-for="Age" placeholder="Enter Your Age" />
    <br />

    <label>Mobile:</label>
    <input asp-for="Mobile" type="number" placeholder="Enter Your Mobile Number" />
    <br />
    <input type="submit" value="Create User" />
</form>

Now, run the application and create a user by visiting /users/create URL, and you will see the respective view to create the user as expected. Instead of using the Complex type, we can also use the primitive data type along with the FromForm attribute. For a better understanding, please modify the UsersController as follows.

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); 
        //    }

        //    // Save user to database or other operations...
        //    // Redirect to another action after successful operation
        //    return RedirectToAction("SuccessAction"); 
        //}

        [HttpPost("users/create")]
        public IActionResult Create([FromForm] string Name, [FromForm] int Age, [FromForm] string Mobile)
        {
            //Validate the Data 
            // Save user to database or other operations...

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

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

Note: Remember to validate the model state (ModelState.IsValid) before processing the data to ensure all model constraints are met and to avoid invalid data scenarios.

When to 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. Here are some scenarios where you’d typically use the FromForm attribute:

Traditional HTML Forms:

One of the most common use cases for FromForm is when dealing with traditional HTML forms. These forms typically send their data as application/x-www-form-urlencoded when the form’s method is POST.

<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 will be sent in the request body in a key-value format separated by &. The FromForm attribute would bind this data to the action method’s parameters or model.

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
}
Complex Models with Form Data:

If you send a mixture of simple fields and complex types via form data, you can use FromForm to bind to complex models.

public class RegisterModel
{
    public string Username { get; set; }
    public string Password { get; set; }
    public Address HomeAddress { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

[HttpPost("/register")]
public IActionResult Register([FromForm] RegisterModel model)
{
    // Handle registration
}

This can handle a form with fields like Username, Password, HomeAddress.Street, and HomeAddress.City.

When Not Using APIs:

If you are building a traditional web application and not an API-centric one, you will use forms more often. In these cases, FromForm becomes the submitted forms’ go-to attribute for model binding.

When Not to Use FromForm:

If you’re building an API, especially one designed to be consumed by other systems, mobile apps, or frontend frameworks like React, Angular, or Vue.js, you will typically work with JSON payloads rather than form data. In such cases, you should use FromBody instead of FromForm.

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 *