skip to Main Content

I create the simple web project which want to use jQuery to pass the data from html to API.

Firstly the model class define as below:

public class Order
{
      public string Name { get; set; } = string.Empty;
      public string OrderCode { get; set; } = string.Empty;
      public string OrderAddress { get; set; } = string.Empty;
      public ICollection<OrderDetail> OrderDetail { get; set; } = new List<OrderDetail>();
}
    
public class OrderDetail
{
   public string ProductCode { get; set; } = string.Empty;
   public int Qty { get; set; }
}

In the ApiController, I have created this method:

 [HttpPost("postorder1")]
 public IActionResult PostOrder1 ([FromForm] Order order)
 {
     Console.WriteLine(JsonSerializer.Serialize(order, Defaults.DefaultJsonSerializerOption));
     return Ok();
 }

The view like

@model Order

<form id="orderform_passquery">
                    <label asp-for="OrderCode" ></label>
                    <input asp-for="OrderCode" type="text" class="form-control"  />
                    <label asp-for="Name"></label>
                    <input asp-for="Name" type="text" class="form-control" />                   
                    <label asp-for="OrderAddress"></label>
                    <textarea asp-for="OrderAddress" class="form-control" ></textarea>        
                    <table id="orderdetail">
                        <thead>
                            <tr>
                                <th>Product Code</th>
                                <th>Product Code</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr>
                               <td data-column="productcode">Item One</td>
                               <td data-column="qty">123</td>
                            </tr>
                        </tbody>
                    </table>                   
                <duv class="mt-1">
                    <button id="cmdSubmit" class="btn btn-primary">Submit</button>
                </div>    
</form>

Then the javascript I create this function

function OnSubmit() {
    var url = "api/data/postorder1";
    var orderTableId = "orderdetail";
    var formPassqueryId = "orderform_passquery";
    const formElement = document.getElementById(formPassqueryId);
    var formData = new FormData(formElement);
   
    const table = document.getElementById(orderTableId);
    var tableData = [];
    const tableRows = table.querySelectorAll("tbody tr");
    tableRows.forEach(function (row) {
        let productCode = row.querySelector('td[data-column="productcode"]').textContent;
        let qty = row.querySelector('td[data-column="qty"]').textContent;
        tableData.push({ productCode, qty });
    });

    formData.append("orderDetail", JSON.stringify(tableData));
    const postData = new URLSearchParams(formData);
    fetch(url, {
        method: "POST",
        body: postData 

    }).then(response => {
        if (response.ok) {
            return response.text()
        }
            return response.text()
                .then(text => { throw new Error(text) })
        }
    )
}

I run the project and input the data and submit.

The result order can return data, but the orderDetail is empty.

I have try to debug in Javascript, they have data inside, can I know how to append orderDetail from table and make it work?

Thank you

2

Answers


  1. It looks like you are trying to pass data from an HTML form, including a table of order details, to a .NET Core API endpoint using jQuery and JavaScript. However, you are facing an issue where the orderDetail parameter is not being populated correctly on the server side. Let’s go through your code and identify the issue.

    In your JavaScript code, you are trying to append the orderDetail array as a JSON string to the formData object:

    javascript

    formData.append("orderDetail", JSON.stringify(tableData));

    This should work in most cases. However, when you use [FromForm] in your API controller action, it expects the data to be in a form format, not a JSON string. To fix this issue, you should modify your JavaScript code to send the data as a properly formatted form field, not as a JSON string.

    You can change your JavaScript code like this:

    javascript

    function OnSubmit() {
    var url = "api/data/postorder1";
    var orderTableId = "orderdetail";
    var formPassqueryId = "orderform_passquery";
    const formElement = document.getElementById(formPassqueryId);

    // Create a new FormData object
    var formData = new FormData();
    
    // Append the form fields to the formData object
    formData.append("Name", formElement.querySelector('input[name="Name"]').value);
    formData.append("OrderCode", formElement.querySelector('input[name="OrderCode"]').value);
    formData.append("OrderAddress", formElement.querySelector('textarea[name="OrderAddress"]').value);
    
    // Get the order detail table data
    const table = document.getElementById(orderTableId);
    var tableData = [];
    const tableRows = table.querySelectorAll("tbody tr");
    tableRows.forEach(function (row) {
        let productCode = row.querySelector('td[data-column="productcode"]').textContent;
        let qty = row.querySelector('td[data-column="qty"]').textContent;
        tableData.push({ ProductCode: productCode, Qty: parseInt(qty) });
    });
    
    // Append the orderDetail array as a serialized form field
    tableData.forEach(function (item, index) {
        formData.append(`OrderDetail[${index}].ProductCode`, item.ProductCode);
        formData.append(`OrderDetail[${index}].Qty`, item.Qty);
    });
    
    // Send the formData object to the API
    fetch(url, {
        method: "POST",
        body: formData
    }).then(response => {
        if (response.ok) {
            return response.text()
        }
        return response.text()
            .then(text => { throw new Error(text) })
    }) }
    

    In this modified code, we are manually appending the form fields and the OrderDetail array as form fields to the formData object. This should ensure that the data is correctly parsed by the [FromForm] attribute in your .NET Core API controller action.

    Make sure that the field names in the formData.append calls match the property names in your Order and OrderDetail classes in the .NET Core API controller. Also, ensure that the Qty is parsed as an integer since it’s defined as an int in your OrderDetail class.

    Login or Signup to reply.
  2. I would do this differently, 1st I will generate the object in JavaScript and then POST it to API as JSON itself. Also remove [FromForm] from the API.

        //get values and assign it to variables
    let name = formElement.querySelector('input[name="Name"]').value;
    let orderCode = formElement.querySelector('input[name="OrderCode"]').value;
    let orderAddress = formElement.querySelector('textarea[name="OrderAddress"]').value;
    
        // Get the order detail table data
        const table = document.getElementById(orderTableId);
        var tableData = [];
        const tableRows = table.querySelectorAll("tbody tr");
        tableRows.forEach(function (row) {
            let productCode = row.querySelector('td[data-column="productcode"]').textContent;
            let qty = row.querySelector('td[data-column="qty"]').textContent;
            tableData.push({ ProductCode: productCode, Qty: parseInt(qty) });
        });
        
    var obj = {
    Name : name,
    OrderCode : orderCode,
    OrderAddress : orderAddress,
    OrderDetail : tableData
    };
        
        // Send the formData object to the API
        fetch(url, {
            method: "POST",
            body: JSON.stringify(obj)
        }).then(response => {
            if (response.ok) {
                return response.text()
            }
            return response.text()
                .then(text => { throw new Error(text) })
        }) }
    

    This should do the work.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search