【问题标题】:How to pass a two dimensional Javascript array from view to controller - Asp.net Core 6 MVC如何将二维 Javascript 数组从视图传递到控制器 - Asp.net Core 6 MVC
【发布时间】:2022-10-24 19:43:56
【问题描述】:

我对 Asp.Net Core 完全陌生,我正在尝试实现一个库存控制系统。现在我面临将销售数据保存到数据库的问题。主要问题是我未能将数据带到控制器。我在数据库中有“销售”、“销售产品”和“产品”表。到目前为止我所尝试的,

Sales Create View 有一个用于选择产品的下拉列表,它使用 SalesViewModel 进行填充:

销售视图模型

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

要创建销售项目列表,每次用户选择产品及其数量时,都会创建“subArray”并将该项目数组推送到“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);

});

数组格式

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

为了将销售数据和销售项目带到控制器,我使用了 FormData 对象和另一个 FormDataViewModel,如this solution 所示

SalesFormDataViewModel

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

我将 SalesViewModel 传递给查看并将 SalesFormDataViewModel 传递给控制器​​。我正在使用 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');
    }
});

控制器

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

实际上,我已经尝试了几乎所有搜索网络的解决方案,但无论尝试什么,每次我得到相同的错误响应。我什至无法到达控制器中的断点,因为 ajax 引发异常。 Ajax Response

拜托,我期待着你的帮助。谢谢你。

我正在编辑此问题以添加更多详细信息。在尝试陈的解决方案后,现在得到this error

【问题讨论】:

  • 好吧,"Each time user select a product and it's quantity, 'subArray' will be created and that item array will be pushed to 'SalesItemArray',",你能告诉我们你是怎么做到的吗?
  • 另外,请问SalesFormDataViewModel类的详细定义是什么?

标签: asp.net asp.net-core asp.net-core-mvc asp.net-core-6.0


【解决方案1】:

400 响应是由于您没有传递ValidateAntiForgeryToken。在制作使用 AJAX 发出的 POST 请求时,很容易忘记防伪令牌。如果您在请求中省略该值,服务器将返回 400 Bad Request 结果。请检查您是否传递了正确的令牌。

方法一:

手动添加标题:

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

更多详情可以参考this link

方法二:

注释掉 ValidateAntiForgeryToken:

//[ValidateAntiForgeryToken]

编辑:

让我们逐步解决您的错误:

看法:

假设你得到的formData是正确的,应该是这样的(注意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>

控制器:

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

【讨论】:

  • 在尝试了您的解决方案后,我认为取得了一些进展。现在 ajax 抛出错误的请求错误“需要 SalesFormDataViewModel 字段”。我已经用错误图像更新了问题。
  • data: JSON.stringify(formData) 更改为data: formData。 @珍珠
  • FormData 本身已经是 Json 格式。
  • 我做了你展示的。这次 ''e​​rrors : {$: ["'S' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0."],…}' 我搜索了这个错误但无法解决然而。
  • 我更新了我的答案,您可以比较它以更快地确认错误原因。 @珍珠
【解决方案2】:

在更改视图模型之前,我无法传递数组。我不得不将字符串数组类型删除为字符串类型。

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

然后,在将数组转换为 json 字符串后,我将数组附加到 formData。

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

在搜索了如何将 formData 发送到控制器之后,在直接通过 ajax 发送 formData 对象之前,我必须做以下事情。

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

然后ajax调用:

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");
    }
});

这样我就能够将二维 js 数组从视图转移到控制器。但是,由于接收到的 SalesItemList 数组是 Json 数组,因此我无法将传递的对象保存到数据库,这是一个异常无法反序列化当前 JSON 数组, 在尝试将该数组反序列化为销售控制器中的对象时抛出。所以,不是传递一个数组数组,而是传递一个对象数组,和上面一样解决了这个问题。

let SalesItemList = [{},{}];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 2020-12-09
    • 2020-06-10
    • 1970-01-01
    • 2015-03-30
    • 2014-06-29
    • 1970-01-01
    相关资源
    最近更新 更多