How to Apply Binding Attributes to Model Properties in ASP.NET Core Web API

How to Apply Binding Attributes to Model Properties in ASP.NET Core Web API

In this article, I will discuss How to Apply Model Binding Attributes to Model Properties in ASP.NET Core Web API Application with Examples, i.e., how to apply FromRoute, FromQuery, and FromHeader Attribute to Model Properties. Please read our previous article discussing Custom Model Binding in ASP.NET Core Web API with Examples.

Applying Model Binding Attributes to Model Properties in ASP.NET Core Web API

In ASP.NET Core Web API, the attributes [FromHeader], [FromQuery], and [FromRoute] are used to specify the source of the values that should be bound to action method parameters. These attributes help to control how data from various parts of an HTTP request is mapped to method parameters, enabling precise handling of incoming data for processing.

Let us understand how to apply Binding Attributes to Model Properties in ASP.NET Core Web API Application with one example. Suppose we are building an API to manage book information. We have an action method to add a new book, where:

  • The book’s Id is passed in the route.
  • The Title of the book is passed in the header.
  • The Author name is passed as a query string parameter.

Let us see how we can implement the above example in the ASP.NET Core Web API Application. First, we will see using simple parameters, then we will see creating a complex object with custom model binding, and finally, we will see how we can achieve the same by applying Binding Attributes to Model Properties in ASP.NET Core Web API Application:

Using Simple Parameter in Controller Action Method

Let us first see how we can implement the example using simple parameters in the controller action method. So, create an API Controller named Book and copy and paste the following code. As you can see, here, we are decorating the Id parameter with FromRoute, Author with FromQuery, and Title with FromHeader Attribute.

using Microsoft.AspNetCore.Mvc;
namespace ModelBinding.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BookController : ControllerBase
    {
        [HttpPost("{Id}")]
        public IActionResult CreateBook([FromRoute]int Id, [FromQuery]string Author, [FromHeader]string Title)
        {
            // Your logic to Store the Data into the database

            //Here, we are simply creating an Anonymous Object and returning the Book details
            var response = new
            {
                BookId = Id,
                BookTitle = Title,
                AuthorName = Author
            };
            return Ok(response);
        }
    }
}
Test the API:

To test the above endpoint, please use the following details. Please change the Port Number where your application is running. Here, you can see that we are passing 100 as the Route value and Pranaya as the query string value for the Author key.

URL: https://localhost:7121/api/Book/100?Author=Pranaya

Method: Post

Header: Title : ASP.NET Core Web API

To test the same using Postman, please see the below image:

How to Apply Model Binding Attributes to Model Properties in ASP.NET Core Web API Application with Examples

Using Custom Model Binder:

Let us see how we can implement the previous example using a Custom Model Binder in ASP.NET Core Web API. So, we need to store the Query String, Route Data, and Header values into a Complex type, and we need to use that complex type as the Action method parameter. So, create a class file named Book.cs and copy and paste the following code.

namespace ModelBinding.Models
{
    public class Book
    {
        // This would be bound from the route
        public int Id { get; set; }

        // This would be bound from the header
        public string Title { get; set; }

        // This would be bound from the query string
        public string Author { get; set; }
    }
}
Creating Custom Model Binder:

Next, we need to create a Custom Model Binder, which will fetch the data from the Query String, Route, and Header. Then, it will create an instance of the Book class and populate the model properties with the values fetching from Query String, Route, and Header. So, let’s create a class file named CustomBookModelBinder.cs and then copy and paste the following code:

using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace ModelBinding.Models
{
    public class CustomBookModelBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            var httpContext = bindingContext.HttpContext;

            // Retrieve from Route
            var routeIdValue = bindingContext.ValueProvider.GetValue("Id").FirstValue;
            if (string.IsNullOrEmpty(routeIdValue))
            {
                bindingContext.Result = ModelBindingResult.Failed();
                return Task.CompletedTask;
            }

            // Retrieve from Query String
            var queryAuthorValue = httpContext.Request.Query["Author"].ToString();
            if (string.IsNullOrEmpty(queryAuthorValue))
            {
                bindingContext.Result = ModelBindingResult.Failed();
                return Task.CompletedTask;
            }

            // Retrieve from Header
            var headerTitleValue = httpContext.Request.Headers["Title"].ToString();
            if (string.IsNullOrEmpty(headerTitleValue))
            {
                bindingContext.Result = ModelBindingResult.Failed();
                return Task.CompletedTask;
            }

            //Creating and Populating the Model
            var book = new Book
            {
                // These keys must be exist in route data, query string and header
                Id = int.Parse(routeIdValue),
                Author = queryAuthorValue,
                Title = headerTitleValue
            };

            // Setting the Model Binding Result
            bindingContext.Result = ModelBindingResult.Success(book);
            return Task.CompletedTask;
        }
    }
}
Apply the Model Binder:

Without creating the Custom Model Binder Provider, we can also directly use the above Custom Model Binder in our action method. So, modify the Book Controller as follows:

using Microsoft.AspNetCore.Mvc;
using ModelBinding.Models;
namespace ModelBinding.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BookController : ControllerBase
    {
        [HttpPost("{Id}")]
        public IActionResult CreateBook([ModelBinder(BinderType = typeof(CustomBookModelBinder))] Book book)
        {
            // Your logic to Store the Data into the database

            return Ok(book);
        }
    }
}

With the above changes in place, run the application, and you should get the output as expected, as shown in the below image:

How to Apply Model Binding Attributes to Model Properties in ASP.NET Core Web API Application

Applying Bind Attribute to Model Properties:

Instead of creating a Custom Model Binder for binding different source data to our model object, we can directly apply the model properties with the required binding Attributes. So, first, modify the Book model as follows. As you can see, we are decorating the model properties with the required Binding Attribute as per our requirement:

using Microsoft.AspNetCore.Mvc;

namespace ModelBinding.Models
{
    public class Book
    {
        [FromRoute(Name = "Id")]
        public int Id { get; set; }

        [FromHeader(Name = "Title")]
        public string Title { get; set; }

        [FromQuery(Name = "Author")]
        public string Author { get; set; }
    }
}

With the above Model Binding Attribute in place, if we use the above model as a parameter in an action method, the Id property will be mapped with the route data, the Title property will be mapped with the Header, and the Author will be mapped with the Query string. So, next, modify the Book Controller as follows:

using Microsoft.AspNetCore.Mvc;
using ModelBinding.Models;
namespace ModelBinding.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BookController : ControllerBase
    {
        [HttpPost("{Id}")]
        public IActionResult CreateBook(Book book)
        {
            // Your logic to Store the Data into the database

            return Ok(book);
        }
    }
}

With the above changes in place, run the application, and you should get the same output as the previous one, as shown in the below image:

Apply Model Binding Attributes to Model Properties in ASP.NET Core Web API

In the next article, I will discuss Content Negotiation in ASP.NET Core Web API with Examples. In this article, I try to explain How to Apply Model Binding Attributes to Model Properties in ASP.NET Core Web API with Examples, and I hope you enjoy this article, “How to Apply Model Binding Attributes to Model Properties in ASP.NET Core Web API.”

Leave a Reply

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