skip to Main Content

I am totally new to Asp.Net Core and I am trying to implement an Inventory controlling system. Now I am facing a problem of saving sales data to database. The main problem is I have failed to bring data to controller. I have ‘sales’, ‘SalesProducts’ and ‘products’ tables in database. What I have tried so far,

Sales Create View has a dropdown to select products and it populates using SalesViewModel:

SalesViewModel

public class SalesViewModel
{
    public Sale Sale { get; set; }
    public List<SelectListItem> Products { get; set; }
}

To create sales items list, each time user select a product and it’s quantity, ‘subArray’ will be created and that item array will be pushed to ‘SalesItemArray’,

$('.btn-sales-add').on('click', function () {
    let subArray = [];
    let productId = $('#product-id').val();
    let productName = $('#product-id option:selected').text();
    let price = $('#sales-price').val();
    let quanity = $('#sales-quantity').val();
    let subTotal = $('#sales-sub-total').val();
    quanity = parseInt(quanity);
    subTotal = parseFloat(subTotal);

    total += subTotal;
    $('#sales-total input').val(total);

    subArray.push(productId);
    subArray.push(productName);
    subArray.push(price);
    subArray.push(quanity);
    subArray.push(subTotal);

    salesItemsArray.push(subArray);

});

Array Format

[[pro_id, pro_name, quantity, subTotal],[pro_id, pro_name, quantity, subTotal]]

To bring the sales data and sales items to controller, I used FormData object and another FormDataViewModel as shown in this solution

SalesFormDataViewModel

 public class SalesFormDataViewModel
{
    public string StoreId { get; set; }
    public string Total { get; set; }
    public string[] SalesItemList { get; set; }
}

I am passing SalesViewModel to view and passing SalesFormDataViewModel to controller. I am posting the data using Ajax,

let storeId = $("#sales-store-id").val();
let total = $("#sales-total input").val();
let salesItemList = salesItemsArray;var 

formData = new FormData();

formData.append("StoreId", storeId);
formData.append("Total", total);
formData.append("salesItemList", salesItemList);

$.ajax({
    url: '/api/sales/createSales',
    method: 'POST',
    contentType: 'application/json',
    data: JSON.stringify(formData),
    success: function (response) {
        alert('success');
    },
    error: function (response, error) {
        alert('error');
    }
});

The Controller

[HttpPost]
[Route("createSales")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> createSales(SalesFormDataViewModel 
salesFormDataViewModel)
{
    return Ok(new { success = "Stock updated successfully" });
}

Actually, I have tried almost every solutions searching the web but whatever tried, everytime I get same error response. I can not even reach to the breakpoint in controler because ajax throws an exception.
Ajax Response

Please, I am expecting all of your help. Thank you.

I am Editing this question to add more details. After trying Chens solution now getsthis error

2

Answers


  1. Chosen as BEST ANSWER

    I could not pass the array until I changed my viewModel. I had to remove the string array type to string type.

     public class SalesFormDataViewModel
     {
         public string StoreId { get; set; }
         public string Total { get; set; }
         public string SalesItemList { get; set; }
     }
    

    Then, I appended the array to formData after converting the array to json string.

    formData.append("SalesItemList", JSON.stringify(SalesItemList));
    

    After searching through how to send formData to controller, before sending the formData object directly via ajax, I had to do following.

    let dataObj = {};
    formData.forEach((value, key) => {
        dataObj[key] = value;
    });
    

    Then ajax call:

    let jsonData = JSON.stringify(dataObj);
    $.ajax({
        url: '/api/Sales/createSales',
        method: 'POST',
        contentType: 'application/json',
        data: jsonData,
        processData: false,
        cache: false,
        success: function (response) {
            alert("success");
        },
        error: function (response) {
            alert("error");
        }
    });
    

    This way I was able to paas two dimensional js array from view to controller. However with this I was unable to achieve save passed object to database since the SalesItemList array being received is a Json array, an exception Cannot deserialize the current JSON array, is thrown when trying to deserialze that array to object in sales controller. So, instead of passing an array of array, passing an array of object, same as above solved the issue.

    let SalesItemList = [{},{}];
    

    I am posting this answer thinking it would help those who face same problem and want to highlight that I am ended up with this solution thanks to those who reply to this question.


  2. The 400 response is due to you not passing ValidateAntiForgeryToken.It is easy to forget about the anti-forgery token when crafting a POST request made with AJAX. If you omit the value from the request, the server will return a 400 Bad Request result. Please check if you are passing the correct Token.

    Method one:

    Add headers manually:

    $.ajax({
       //...
       headers: { "RequestVerificationToken": yourtoken },
       //...
    });
    

    For more detail, you can refer to this link.

    Method two:

    Comment out ValidateAntiForgeryToken:

    //[ValidateAntiForgeryToken]
    

    Edit:

    Let’s troubleshoot your mistakes step by step:

    View:

    Assuming the formData you got is correct, it should be something like this(Pay attention to several properties of ajax):

    <script>
        function Test()
        {
            let storeId = 1;
            let total = "Total";
            let salesItemList = [[1, "Name1", "quantity1", "subTotal1"], [2, "Name2", "quantity2", "subTotal2"]];
    
            var formData = new FormData();
    
            formData.append("StoreId", storeId);
            formData.append("Total", total);
            formData.append("salesItemList", salesItemList);
    
            $.ajax({
                url: '/createSales',
                method: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                cache: false,
                async: false,
                success: function (response) {
                    alert('success');
                },
                error: function (response, error) {
                    alert('error');
                }
            });
        }
    
    </script>
    

    Controller:

    [HttpPost]
    [Route("createSales")]
    public async Task<IActionResult> createSales(SalesFormDataViewModel
                salesFormDataViewModel)
    {
         return Ok(new { success = "Stock updated successfully" });
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search