Search code examples
javascriptxmlhttprequestasp.net-core-webapiform-data

"400 bad request" when posting data to asp.net core web api with FormData in XmlHttpRequest


I have a ASP.Net Core web API with this action :

    // POST api/TodoList
    [HttpPost]
    public void Post([FromBody] Tache tache)
    {
       TodoListContext.AjouterTache(tache);
    }

Here is the code of the Tache entity :

    public class Tache
    {
       public int Id { get; set; }

       [DataType(DataType.MultilineText)]
       [Required, MaxLength(250)]
       public string Description { get; set; }

       [DataType(DataType.Date)]
       public DateTime DateCreation { get; set; }

       [DataType(DataType.Date)]
       public DateTime DateEcheance { get; set; }

       public int Priorite { get; set; }

       public bool Terminee { get; set; }
    }

I call the action from a javascript SPA, with XHR like this :

    function ajouterTache() {
       // Construit un objet Tâche à partir des valeurs saisies
       let tache = {}; 
       tache.id = document.getElementById("idTache").value;
       tache.dateCreation = document.getElementById("dateCreation").value;
       tache.dateEcheance = document.getElementById("dateEcheance").value;
       tache.priorite = document.getElementById("priorite").value;
       tache.terminee = document.getElementById("terminee").checked;
       tache.description = document.getElementById("description").value; 
       console.log(tache);

       // Envoie la tâche à l'API
       const req = new XMLHttpRequest();
       req.onload = function () {
          ...
       };

       req.open('POST', uri, true);
       req.setRequestHeader("Content-Type", "application/json");
       req.send(JSON.stringify(tache));
    }

The code above works fine, but this one does not :

    function ajouterTache() {
       data = new FormData(document.getElementById("formEdit"));

       // Envoie la tâche à l'API
       const req = new XMLHttpRequest();
       req.onload = function () {
        ...
       };

       req.open('POST', uri, true);
       req.setRequestHeader("Content-Type", "application/json");
       req.send(data);
    }

Each field of the form has a correct name, is enabled and contains valid input.

But I always get à "400 : bad request" response.
Debug tools of Firefox show the following error in the XHR result :

Input string '-----------------------------18691991225667' is not a valid number. Path '', line 1, position 43.
title : One or more validation errors occurred

I added this code before sending the xhr to watch the content of the data object :

    let formData = new FormData(document.getElementById("formEdit"));
    for (let pair of formData.entries()) {
       console.log(pair[0] + ': ' + pair[1] + ", " + typeof pair[1]);
    }

Here is the result :

idTache: 11
dateCreation: 2019-10-08
dateEcheance: 2019-10-22
priorite: 1
terminee: on
description: essai

It seems to be correct. So what is wrong with my using of FormData ?


Solution

  • If you would like to post data with FormData, then you should not set Content-Type to application/json.Besides, use [FromForm] instead of [FromBody] on your action parameter.

    1.Remove below line in js code

    req.setRequestHeader("Content-Type", "application/json");
    

    2.Use [FromForm]

    [HttpPost]
     public void Post([FromForm] Tache tache)
    

    Here is the result :

    idTache: 11 dateCreation: 2019-10-08 dateEcheance: 2019-10-22 priorite: 1 terminee: on description: essai

    Since you receive the data as a model Type Tache, you need to pass a property named id instead of idTache shown in your log result.

    You do not show your view code,I suggest that you use name="id" for that input textbox.

    The correct log result in my case has a __RequestVerificationToken:,it is also expeted if you use <form id="formEdit">:

    id: 11
    dateCreation: 2019-10-08
    dateEcheance: 2019-10-22
    priorite: 1
    terminee: on
    description: essai
    __RequestVerificationToken:xxxxxxxx