简体   繁体   English

ASP.Net MVC 将表数据从视图发送到 controller

[英]ASP.Net MVC Sending Table data from view to controller

I have a table in my view for what is essentially my attempt at making a timesheet table.我在我的视图中有一个表格,基本上是我尝试制作时间表表格。 It also contains a button for adding more rows to the table.它还包含一个用于向表格添加更多行的按钮。

<table class="table table-bordered table-responsive table-hover" id="mytab" cellspacing="0" cellpadding="0">  
        <thead>
            <tr>  
                <th>Project</th>   
                <th>Discipline</th>  
                <th>Mo</th>  
                <th>Tu</th>  
                <th>We</th>  
                <th>Thu</th>  
                <th>Fri</th>  
                <th>Sat</th>  
                <th>Sun</th>  
                <th></th>
            </tr>  
        </thead>
        <tr>
            <td><select name="selectedProjectId" asp-items="@ViewData["projectSubProject"] as SelectList" class="form-control-plaintext align-content-around">
            </select></td>  
            <td><select name="selectedPositionId" asp-items="@ViewData["Positions"] as SelectList" class="form-control-plaintext align-content-around"></select></td>  
            <td><input class="form-control-plaintext align-content-around txtCal" type="number" min="1" max="24"/></td>  
            <td><input class="form-control-plaintext align-content-around txtCal" type="number" min="1" max="24"/></td>  
            <td><input class="form-control-plaintext align-content-around txtCal" type="number" min="1" max="24"/></td>  
            <td><input class="form-control-plaintext align-content-around txtCal" type="number" min="1" max="24"/></td>  
            <td><input class="form-control-plaintext align-content-around txtCal" type="number" min="1" max="24"/></td>  
            <td><input class="form-control-plaintext align-content-around txtCal" type="number" min="1" max="24"/></td>  
            <td><input class="form-control-plaintext align-content-around txtCal" type="number" min="1" max="24"/></td> 
        </tr>
    </table> 
    <br />
    <form action="">
        <input type="button" value="Add a Row" onclick="addRow()">
    </form>

It looks like this in the web page在 web 页面中看起来像这样

The script for adding rows to the table and the script for what should , from what i gather, send the table data in json format to controller on table data change look like this:用于向表中添加行的脚本和该做什么的脚本,从我收集的内容来看,将 json 格式的表数据发送到表数据更改的 controller 如下所示:

$(document).ready(function(){
        $("#myTable").on('input', '.txtCal', function () {
               var calculated_total_sum = 0;
 
               $("#myTable .txtCal").each(function () {
                   var get_textbox_value = $(this).val();
                   if ($.isNumeric(get_textbox_value)) {
                      calculated_total_sum += parseFloat(get_textbox_value);
                      }                  
                    });
                      $("#total_sum_value").html(calculated_total_sum);
               });

        });

        function addRow() {
            var root = document.getElementById('mytab').getElementsByTagName('tbody')[0];
            var rows = root.getElementsByTagName('tr');
            var clone = cloneEl(rows[rows.length - 1]);
            cleanUpInputs(clone);
            root.appendChild(clone);
        }
        
        function cloneEl(el) {
            var clo = el.cloneNode(true);
            return clo;
        }

        function cleanUpInputs(obj) {
          for (var i = 0; n = obj.childNodes[i]; ++i) {
            if (n.childNodes && n.tagName != 'INPUT') {
              cleanUpInputs(n);
            } else if (n.tagName == 'INPUT' && n.type == 'number') {
              n.value = '';
            }
          }  
        }

        $('input').change(function () {
            var table = document.getElementById("mytab");
            var rows = table.getElementsByTagName("tr");
            var data = [];
            for (var i = 0; i < rows.length; i++) {
                var cells = rows[i].getElementsByTagName("td");
                var row = [];
                for (var j = 0; j < cells.length; j++) {
                    var cell = cells[j];
                    row.push(cell.innerText);
                }
                data.push(row);
            }
            $.ajax({
                type: "POST",
                url: '@Url.Action("TableList", "Home")',
                data: JSON.stringify(data),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    alert("success");
                },
                failure: function (data) {
                    alert("can not update the timesheet");
                }
            });
        });

And finally, my controller methods look like this:最后,我的 controller 方法如下所示:

public async Task<IActionResult> TableList()
    {
        var projectSubProject = await _context.SubProject.Include(x => x.Project).ToListAsync();
        ViewData["projectSubProject"] = new SelectList(projectSubProject, "Id", "DisplayId");
        ViewData["Positions"] = new SelectList(await _context.Position.ToListAsync(), "Id", "Title");

        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> TableList(string JSON)
    {
        if (ModelState.IsValid)
        {
            var list = JsonConvert.DeserializeObject(JSON);
        }

        return View();
    }

The problem that i think i'm encountering is that the JSON data doesn't actually reach the controller, since putting a break point anywhere on the Post method doesn't ever trigger it.我认为我遇到的问题是 JSON 数据实际上并没有到达 controller,因为在 Post 方法的任何地方放置断点都不会触发它。

Am i doing something wrong?难道我做错了什么? Am i missing some crucial step?我错过了一些关键的步骤吗? Is there perhaps an easier way of doing what i want to do?是否有更简单的方法来做我想做的事情?

I would probably use a Model for that something like a Row class list.我可能会使用 Model 来表示行 class 列表。

Like this:像这样:

public class Row
{
    public string Project   {get;set;}
    public string Discipline {get;set;} 
    public string Mo  {get;set;}
    public string Tu  {get;set;}
    public string We  {get;set;}
    public string Thu  {get;set;}
    public string Fri  {get;set;}
    public string Sat  {get;set;}
    public string Sun  {get;set;}
}

public class TableModel
{
    public List<Row> Rows {get; set;}
}

And then I would set all the actions to interact with the model.然后我将设置所有操作以与 model 交互。

This would make your work easier.这将使您的工作更轻松。

I also suggest to take a look at the microsoft documentation since you are missing the use of models.我还建议您查看microsoft 文档,因为您缺少模型的使用。

There're several points you need to care.您需要注意几点。 Firstly, you are now trying to use ajax to send post request to your controller, it's different from the default form submit in asp.net core MVC.首先,您现在尝试使用 ajax 向您的 controller 发送 post 请求,这与 asp.net 核心 MVC 中的默认表单提交不同。 Hence, [ValidateAntiForgeryToken] and if (ModelState.IsValid) are not suitable for your scenario.因此, [ValidateAntiForgeryToken]if (ModelState.IsValid)不适合您的场景。

Then, when you use data: JSON.stringify(data) to set it as the request data, it will generate payload like this, you can't use string to receive the data, you need to use List<object> data :然后,当你使用data: JSON.stringify(data)将其设置为请求数据时,它会生成这样的payload,你不能使用string来接收数据,你需要使用List<object> data

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

You may change your code like this:您可以像这样更改代码:

@section Scripts{
    <script>
        $("#btn1").click(function(){
            var data = [];
            var row1 = [1, 2, 3, 4, 5];
            var row2 = [6,7,8,9,10];
            data.push(row1);
            data.push(row2);
            $.ajax({
                url: "https://localhost:7175/Home/TableList",
                type: "post",
                data: JSON.stringify(data),
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: function (data) {
                    alert(data);
                }
            });
        });
    </script>
}

[HttpPost]
//[ValidateAntiForgeryToken]
public string TableList([FromBody]List<object> data)
{
    //if (ModelState.IsValid) { 
    //    var list = JsonConvert.DeserializeObject(json);
    //}
    return "hello";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM