अजपा योग क्रिया आणि ध्यान : श्वास, मंत्र, मुद्रा आणि ध्यान यांच्या सहाय्याने मनःशांती, एकाग्रता, चक्र संतुलन आणि कुंडलिनी जागृती. अधिक माहिती आणि आगामी तारखांसाठी येथे जा.


Automatic Model Validation and Parameter Binding using ApiController Attribute

While developing ASP.NET Core Web API you need to perform model validation manually. You also need to bind action parameters explicitly using attributes such as [FromBody]. The [ApiController] attribute introduced in ASP.NET Core 2.1 can automate both of these tasks for you. This article explains how.

Consider the following Post() action from a Web API controller - CustomerController.

[Route("api/[controller]")]
public class CustomerController : Controller
{
    [HttpPost]
    public IActionResult Post([FromBody]Customer obj)
    {
        if(ModelState.IsValid)
        {
            //insert customer
            return Ok();
        }
        else
        {
            return BadRequest();
        }
    }
}

The CustomerController contains just a single action - Post() - that is supposed to insert a new customer in the database. Notice a couple of things about this action:

  • The action checks the ModelState.IsValid manually. And depending on the outcome either returns 200 - Ok or 400 - Bad request as its response.
  • The Post() action takes one parameter - obj - that is bound with the incoming request body using [FromBody] attribute. In the absence of [FromBody] obj will be null even though the client sends data as a part of request body.

The Customer model class involved in the Web API is shown below:

public class Customer
{
    [Required]
    [StringLength(5)]
    public string ID { get; set; }

    [Required]
    [StringLength(50)]
    public string Name { get; set; }
}

Notice the use of validation attributes such as [Required] and [StringLength] to validate Customer ID and Name properties.

Wouldn't it be nice if these simple yet common tasks are taken care of by the framework itself? That's what [ApiController] attribute does.

Let's see how to use it. Have a look at the following code:

[Route("api/[controller]")]
[ApiController]
public class CustomerController : Controller
{
    [HttpPost]
    public IActionResult Post(Customer obj)
    {
       //insert customer
       return Ok();
    }
}

Notice that the CustomerController is now decorated with [ApiController] attribute. The Post() action no longer has the model validation code. Moreover, the obj parameter is not explicitly bound with the request body using [FromBody] attribute. All these aspect are automatically taken care by the [ApiController] attribute.

Since [ApiController] is introduced in ASP.NET Core 2.1 you also need to set the compatibility version in the Startup class as shown below:

public void ConfigureServices(IServiceCollection services)
{
    services
    .AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

The SetCompatibilityVersion() method sets the compatibility to version 2.1. This line of code is required for [ApiController] to work as expected. So, make sure to add in your application startup as explained above.

Now that we have [ApiController] in place, let's test whether it works as expected. The following jQuery code makes a POST request to the CustomerController.

$(document).ready(function () {

    var options = {};
    options.url = "/api/customer";
    options.type = "POST";
    options.contentType = "application/json";

    var obj = {};
    obj.ID = "AFLKI";
    obj.Name = "Company Name 1";

    options.data = JSON.stringify(obj);
    options.dataType = "json";
    options.success = function () {
        console.log("Success!");
    };
    options.error = function (a,b,c) {
        console.log(a);
        console.log(b);
        console.log(c);
    };

    $.ajax(options);
});

The above code creates a new Customer object (with ID and Name properties) and sets the data property. The $.ajax() initiates the POST request to the Web API.

Set a breakpoint in the Post() action and run the application.

If you pass valid values for ID and Name properties, the POST request will reach the Post() action breakpoint. Moreover, the obj parameter will have correct ID and Name values even if you didn't use [FromBody] attribute.

Now, set some invalid value for ID property, say - ALFKI123 (more than 5 characters) and run the application again. This time the framework will detect that ModelState is invalid and will respond with 400 - Bad request to the browser. This automatic model state checking happens due to [ApiController] attribute. Since the framework is detecting the error before reaching the the Post() action, the breakpoint will not be reached.

The following figure shows how the browser is sent a 400 - Bad Request message.

Notice how the validation error message from the validation attributes is available to the client via responseText property in addition to status and statusText properties.

That's for now! Keep coding!!


Bipin Joshi is an independent software consultant and trainer by profession specializing in Microsoft web development technologies. Having embraced the Yoga way of life he is also a meditation teacher and spiritual guide to his students. He is a prolific author and writes regularly about software development and yoga on his websites. He is programming, meditating, writing, and teaching for over 27 years. To know more about his ASP.NET online courses go here. More details about his Ajapa Japa and Shambhavi Mudra online course are available here.

Posted On : 01 October 2018