【问题标题】:How can i insert data from a table row into Database on clicking a button in the row in C# MVC如何在 C# MVC 中单击行中的按钮时将表行中的数据插入数据库
【发布时间】:2020-08-04 19:17:44
【问题描述】:

我有一个 MVC 应用程序,它将数据填充到表中并显示它。每个表行都有一个按钮,可以将数据保存到数据库中。我知道如何保存来自控制器的数据,我只想知道如何将点击的表格行中的数据传递给控制器​​?

@foreach (var item in Model.Properties)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.GrossYield)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.listPrice)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.monthlyRent)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.yearBuilt)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Addresses.address1)
                <br />
                @Html.DisplayFor(modelItem => item.Addresses.address2),
                @Html.DisplayFor(modelItem => item.Addresses.district),
                @Html.DisplayFor(modelItem => item.Addresses.state),
                @Html.DisplayFor(modelItem => item.Addresses.zip),
                @Html.DisplayFor(modelItem => item.Addresses.country).
            </td>
            <td>
                <button class="clsActionButton" id="idAddButton" onclick="idAddButton_onclick();">Add</button>
             </td>
        </tr>
    }

这是我的表格,用于填充模型中的数据。当我单击添加按钮时,我想将整行数据发送到控制器。

【问题讨论】:

  • 为了做到这一点,您基本上有 2 个选择:1) 在每一行上都有一个表单元素,以便按钮用作提交按钮 2) 编写 JavaScript 以手动获取数据并回发到服务器。这两种方法都不能很好地工作 IMO:1)不允许表单是 的直接子级 2)您必须编写许多硬编码的 JavaScript 代码来获取每个单元格的数据。当事情发生变化时,整个事情变得越来越难以维护。我建议您采用不同的方法:将表格视图保留为摘要视图。在每一行,你可以有一个 href 为每一行打开一个模式。
  • 模态/弹出窗口(甚至可能是一个单独的页面)将有一个视图模型,它只代表一行记录(可能带有标识符)。
  • @DavidLiang 这个时候,我相信我会因为时间限制想去 JS 代码。我在网上找不到任何关于如何使用 JS 发送数据的信息,而且我对此知之甚少。你能帮我写一段代码吗?
  • 好的。您需要发回哪些数据?全部?
  • @DavidLiang - 是的,无论单击哪个行按钮,整个行数据都是如此。我希望它到达我的控制器,在那里我编写了将其传递给数据库的代码。非常感谢。

标签: c# html asp.net-mvc


【解决方案1】:

David Liang 提出了一些很好的观点。也许这种方法对你有用。基本思想是将每一行的数据转换成JSON。然后将 JSON 发送到服务器。因为我们使用服务,即 NewtonSoft.Json,来序列化和反序列化数据,我们避免了 David Liang 提到的硬编码值问题。

我编写了一个演示来展示这种方法。我已尝试将其与您的相同,但由于您没有包括所有内容,因此不得不进行猜测。

首先,您需要安装 nuget 包 Newtonsoft.Json。

这是服务器端代码,即 viewModel 和控制器。 GET 只是将测试数据发送到视图。 POST 方法是您感兴趣的方法,它接受 JSON 字符串并将其反序列化以提供您的行对象。

using Newtonsoft.Json;
using System.Collections.Generic;
using System.Web.Mvc;

namespace InsertRow.Controllers
{
    public class MyViewModel
    {
        public List<BuildingViewModel> Properties { get; set; }
    }

    public class BuildingViewModel
    {
        public string GrossYield { get; set; }
        public string listPrice { get; set; }
        public string monthlyRent { get; set; }
        public string yearBuilt { get; set; }
        public AddressViewModel Addresses { get; set; }
    }

    public class AddressViewModel
    {
        public string address1 { get; set; }
        public string address2 { get; set; }
        public string district { get; set; }
        public string state { get; set; }
        public string zip { get; set; }
        public string country { get; set; }
    }

    public class HomeController : Controller
    {       
        public ActionResult Index()
        {
            var myTestData = new List<BuildingViewModel>()
            {
                new BuildingViewModel
                {
                    GrossYield = "gy1",
                    listPrice = "lp1",
                    monthlyRent = "mr1",
                    yearBuilt = "yb1",
                    Addresses = new AddressViewModel
                    {
                        address1 = "a11",
                        address2 = "a21",
                        district = "d1",
                        state = "s1",
                        zip = "z1",
                        country = "c1"
                    }
                },
                new BuildingViewModel
                {
                    GrossYield = "gy2",
                    listPrice = "lp2",
                    monthlyRent = "mr2",
                    yearBuilt = "yb2",
                    Addresses = new AddressViewModel
                    {
                        address1 = "a12",
                        address2 = "a22",
                        district = "d2",
                        state = "s2",
                        zip = "z2",
                        country = "c2"
                    }
                }
            };

            var viewModel = new MyViewModel
            {
                Properties = myTestData
            };           

            return View(viewModel);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(string rowJson)
        {
            var data = JsonConvert.DeserializeObject<BuildingViewModel>(rowJson);
            //code to save the data to the database goes here.
            return RedirectToAction("index");
        }
    }
}

这里是 index.cshtml 文件

@using InsertRow.Controllers
@using Newtonsoft.Json
@model MyViewModel

@Html.AntiForgeryToken()
<table>
    <tbody>
        @foreach (var item in Model.Properties)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.GrossYield)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.listPrice)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.monthlyRent)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.yearBuilt)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Addresses.address1)
                    <br />
                    @Html.DisplayFor(modelItem => item.Addresses.address2),
                    @Html.DisplayFor(modelItem => item.Addresses.district),
                    @Html.DisplayFor(modelItem => item.Addresses.state),
                    @Html.DisplayFor(modelItem => item.Addresses.zip),
                    @Html.DisplayFor(modelItem => item.Addresses.country).
                </td>
                <td>
                    <button data-row="@JsonConvert.SerializeObject(item)"
                            class="clsActionButton">Add</button>
                </td>
            </tr>
        }
        </tbody>
</table>

<script>
    var addButtons = document.querySelectorAll(".clsActionButton");
    var addButtonCount = addButtons.length;
    for (var i = 0; i < addButtonCount; i++) {
        addButtons[i].addEventListener('click', onAddRowClicked);
    }

    function onAddRowClicked(e) {
        e.preventDefault();
        var btn = this;
        var data = btn.dataset.row;
        var form = document.createElement("form");
        form.method = "post";
        form.action = '/home/index';
        var antiForgeryInput = document.querySelector('input[name="__RequestVerificationToken"]');
        form.appendChild(antiForgeryInput); 
        var input = document.createElement('input');
        input.setAttribute("type", "hidden");
        input.setAttribute("value", data);
        input.setAttribute("name", "rowJson");
        form.appendChild(input); 
        document.body.appendChild(form);
        form.submit();
    }
</script>

注意我对按钮做了什么。我已将该行的所有数据添加为数据属性。这种方法的好处是,如果将来数据发生变化,此按钮的代码可以保持不变。

还要注意 javascript。单击按钮时,我们会即时创建一个表单,添加防伪令牌和来自单击按钮的数据,然后提交到服务器。服务器反序列化后,您将获得所需的行数据。

【讨论】:

  • 非常感谢,戴夫,这就是我要找的。是的,后来我意识到我所有的按钮都有相同的 id,所以我删除了它,但忘了在这里编辑它。
猜你喜欢
  • 2014-06-20
  • 2015-03-30
  • 2021-12-06
  • 2015-04-10
  • 2012-02-24
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多