ASP.Net Core: Post JSON data to Api Controller

To post JSON data to web api controller in MVC Core is little bit change.


public class StudentController : Controller  
{
    [HttpPost]
    public IActionResult AddStudent(Student student)
    {
        return Ok();
    }
}
public class Student  
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

Here we have a model student and a Post Method in StudentController i.e. AddStudent. So where does the Student parameter come from? Model binding to the rescue! There are a number of different places the model binders can look for data in order to hydrate the person object. The model binders are highly extensible, and allow custom implementations, but common bindings include:
  • Route values - navigating to a route such as {controller}/{action}/{id} will allow binding to an idparameter
  • Querystrings - If you have passed variables as querystring parameters such as ?FirstName=Frank, then the FirstName parameter can be bound.
  • Body - If you send data in the body of the post, this can be bound to the Person object
  • Header - You can also bind to HTTP header values, though this is less common.
In a simple web page, we then make POSTs (using jQuery for convenience), sending requests either x-www-form-urlencoded (as you would get from a normal form POST) or as JSON.
 //form encoded data
 var dataType = 'application/x-www-form-urlencoded; charset=utf-8';
 var data = $('form').serialize();

 //JSON data
 var dataType = 'application/json; charset=utf-8';
 var data = {
    FirstName: 'Alan',
    LastName: 'Cook',
    Age: 19
 }

 console.log('Submitting form...');
 $.ajax({
    type: 'POST',
    url: '/Person/Index',
    dataType: 'json',
    contentType: dataType,
    data: data,
    success: function(result) {
        alert('Data received: ');

    }
});
Using the above HTTP requests, we notice that the x-www-url-formencoded POST is working correctly, but the JSON POST is not.
SOLUTION:
In order to bind the JSON correctly in ASP.NET Core, you must modify your action to include the attribute [FromBody] on the parameter. This tells the framework to use the content-type header of the request to decide which of the configured IInputFormatters to use for model binding.
By default, when you call AddMvc() in Startup.cs, a JSON formatterJsonInputFormatter, is automatically configured, but you can add additional formatters if you need to, for example to bind XML to an object.

NOW GETTING ANOTHER ISSUE:

When you use [FromBody] in your methods, you will get an error "415 - Unsupported Media Type" when contentType = x-www-url-formencoded in your ajax request.

To resolvbe this issue you have to either remove the FromBody attribute or add the alternative FromForm attribute, both of which will allow our form data to be bound but again you will getting issue when POSTing JSON data.


You have to use only one in a case or if you need both then you have to write two methods in your web api controller to handle both type of requests:

public class StudentController : Controller  
{
    //This action at /Student/AddStudent can bind form data 
    [HttpPost]
    public IActionResult AddStudent(Student student){
        // TO DO WORK
        return Ok();   
    } 

    //This action at /Student/AddStudentFromBody can bind JSON     [HttpPost]
    public IActionResult AddStudentFromBody([FromBody] Student student){
        // TO DO WORK
        return Ok();   
    } 

}








Comments

Popular posts from this blog

Data Bound Controls in ASP.Net - Part 4 (FormView and DetailsView controls)

ASP.net: HttpHandlers

The Clickjacking attack and X-Frame-Options