asp.net-corepostmodel-view-controllerfetch-api

How can I pass post parameters from JS to MVC controller?


I have the following JS code:

const data = await fetch("/api/database/sample", 
{ 
    method: "post", 
    headers: { "Content-Type": "application/json; charset=UTF-8" },
    body: JSON.stringify({ names: ['ahmad', 'mutawa'], age: 22 })

});

Developers tools

This code successfully triggers the following method in a Mvc Controller (in a .net core 8 application):

[Route("api/[controller]")]
public class DatabaseController: Controller
{
    [HttpPost("sample")]
    public IActionResult Sample(string[] names, int age)
    {
        // names = []    // why ????
        // age   = 0     
        return Json(/* some object array */);
    }
}

The only issue is, the parameters names and age are set to default 'empty or nullfor names, and0forage`.

missing values for the parameters

I changed the Content-Type to urlencoded-form, and that allowed me to set the age successfully, but the names array is treated as a single string variable, meaning all values within the array are inserted into the first element.

How do I resolve this issue?


Solution

  • If you don't want use dto to bind the data, you can change your backend code like below to fix the issue.

    using Microsoft.AspNetCore.Mvc;
    using Newtonsoft.Json.Linq;
    
    namespace WebApplication9.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class DatabaseController : ControllerBase
        {
            [HttpPost("sample")]
            public IActionResult Sample(Dictionary<string, object> payload)
            {
                // names = []    // why ????
                // age   = 0     
    
                var names = payload["names"] as JArray; 
                var age = Convert.ToInt32(payload["age"]);
                return Ok(new { names, age });
    
            }
         }
    }
    

    enter image description here

    Recommended Solution

    Use FromBody attribute to bind the data.

    using Microsoft.AspNetCore.Mvc;
    using Newtonsoft.Json.Linq;
    
    namespace WebApplication9.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        public class DatabaseController : ControllerBase
        {
            [HttpPost("sample")]
            public IActionResult Sample([FromBody] SampleRequest request)
            {
                var names = request.Names;  
                var age = request.Age;      
                return Ok(names);
            }
    
            public class SampleRequest
            {
                public string[] Names { get; set; }
                public int Age { get; set; }
            }
        }
    }