【发布时间】:2018-01-08 20:23:18
【问题描述】:
我有一个表格,其中有一个空列,用户可以在其中输入评论:
Table
-----
TbMapId | UniqueAdp | Dealership | Line
--------------------------------------------------------------------
1 | [Insert comment here] | Derby | abc123
2 | [Insert comment here] | Keighley | cda345
3 | [Insert comment here] | Manchester | 876ghj
要评论的数据很多,我不能指望用户打开“编辑”页面并一一输入评论。相反,我需要用户能够输入一堆 cmets(一次 20 个,对 20 行),并通过单击提交按钮将它们全部保存。
如果您想直接跳到工作解决方案,请转到 EDIT #2 并查看 Rudi 接受的答案
查看
<form asp-action="TbMapViewEdit">
<div class="col-lg-6">
<div class="row">
<input type="submit" value="Save" class="btn btn-primary" />
<div class="col-md-12">
<table class="table table-condensed table-bordered table-hover">
<thead>
<tr>
<td><b>TEMP ID</b></td>
<td><b>Map To</b></td>
<td><b>Accounts Code</b></td>
<td><b>Line</b></td>
<td><b>Map Result</b></td>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.TBMapBalancesList.Count; i++)
{
<tr>
<td>
@Html.DisplayFor(Model => Model.TBMapBalancesList[i].TbMapId)
@Html.HiddenFor(Model => Model.TBMapBalancesList[i].TbMapId)
</td>
<td>@Html.EditorFor(Model => Model.TBMapBalancesList[i].UniqueAdp, new { @class = "control-label_DI" })</td>
<td>@Html.DisplayFor(Model => Model.TBMapBalancesList[i].AccountsCode)</td>
<td>@Html.DisplayFor(Model => Model.TBMapBalancesList[i].Line)</td>
<td>@Html.DisplayFor(Model => Model.TBMapBalancesList[i].MapResult)</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</form>
型号
我今天了解到,我需要使用 List 才能通过使用 @for 循环(如上所示)来遍历表中的行。在我尝试使用 IEnumerable 之前。所以我在模型中添加了public List<TBMapBalances> TBMapBalancesList { get; set; }的定义
public class TbMapViewModel
{
public IEnumerable<ASPNET_Core_1_0.Models.TBMapBalances> TBMapBalances { get; set; }
public IEnumerable<ASPNET_Core_1_0.Models.TBMapUniqueADP> TBMapUniqueADP { get; set; }
public List<TBMapBalances> TBMapBalancesList { get; set; }
[...]
}
控制器:
现在这是我需要帮助的地方,我的代码根本不会抛出任何错误。当我按下提交时,没有任何反应:
[Authorize]
[HttpPost]
public async Task<IActionResult> TbMapViewEdit(TbMapViewModel tbMapViewModel)
{
if (ModelState.IsValid)
{
foreach (var TbListId in tbMapViewModel.TBMapBalancesList)
{
var getCode = _context.TBMapBalances.Where(p => p.TbMapId == TbListId.TbMapId).FirstOrDefault();
if (getCode != null)
{
getCode.TbMapId = TbListId.TbMapId;
}
}
try
{
_context.Update(tbMapViewModel.TBMapBalances);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
throw;
}
}
return RedirectToAction("TbMapView");
}
编辑#1
视图更改
<form asp-action="TbMapViewEdit">
<div class="col-lg-6">
<div class="row">
<input type="submit" value="Save" class="btn btn-primary" />
<div class="col-md-12">
<table class="table table-condensed table-bordered table-hover">
<thead>
<tr>
<td><b>TEMP ID</b></td>
<td><b>Map To</b></td>
<td><b>Accounts Code</b></td>
<td><b>Line</b></td>
<td><b>Map Result</b></td>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.TBMapBalances.Count; i++)
{
<tr>
<td>
@Html.DisplayFor(Model => Model.TBMapBalances[i].TbMapId)
@Html.HiddenFor(Model => Model.TBMapBalances[i].TbMapId)
</td>
<td>@Html.EditorFor(Model => Model.TBMapBalances[i].UniqueAdp, new { @class = "control-label_DI" })</td>
<td>@Html.DisplayFor(Model => Model.TBMapBalances[i].AccountsCode)</td>
<td>@Html.DisplayFor(Model => Model.TBMapBalances[i].Line)</td>
<td>@Html.DisplayFor(Model => Model.TBMapBalances[i].MapResult)</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
</form>
模型变化
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ASPNET_Core_1_0.Models.TbMapViewModels
{
public class TbMapViewModel
{
public IEnumerable<ASPNET_Core_1_0.Models.TBMapUniqueADP> TBMapUniqueADP { get; set; }
public List<TBMapBalances> TBMapBalances { get; set; }
[...]
}
}
对控制器的更改:
现在这是我需要帮助的地方,我的代码在当前状态下根本不会抛出任何错误 - 当我按下提交时,没有任何反应,也没有数据保存到数据库中。
但是,当您取消注释行 _context.Update(tbMapViewModel.TBMapBalances);我收到一个错误,指出 List 不是任何模型的一部分并且找不到。
另外,下面的代码是我写的,试图遵循这个 SO 帖子:update-multiple-records-at-once-in-asp-net-mvc - 最初我试图让它异步,但我得到了更多错误,无法继续。我想我会尽可能密切关注它,希望它能给我一个工作的起点。
[Authorize]
[HttpPost]
public IActionResult TbMapViewEdit(TbMapViewModel tbMapViewModel)
{
if (ModelState.IsValid)
{
foreach (var TbListId in tbMapViewModel.TBMapBalances)
{
var getCode = _context.TBMapBalances.Where(p => p.TbMapId == TbListId.TbMapId).FirstOrDefault();
if (getCode != null)
{
getCode.TbMapId = TbListId.TbMapId;
}
}
// _context.Update(tbMapViewModel.TBMapBalances);
_context.SaveChanges();
}
return RedirectToAction("TbMapView");
}
编辑 #2 - 救援英雄 - 非常感谢 @RudiVisser 的帮助
首先,如果你们中的任何人 - 像我一样 - 卡在使用 .net core 1.0.0 确保首先升级到最新版本(1.1.7 lts)。我的部分悲痛是我是 USER 1.0 并且没有升级我的安装,因为修复和添加不断出现。不要像我一样成为那个人......
以下均感谢 Rudi 的帮助:
查看
@using (Html.BeginForm("TbMapViewEdit", "TbMap"))
{
<div class="col-lg-6">
<div class="row">
<input type="submit" value="Save" class="btn btn-primary" />
<div class="col-md-12">
<table class="table table-condensed table-bordered table-hover">
<thead>
<tr>
<td><b>TEMP ID</b></td>
<td><b>Map To</b></td>
<td><b>Accounts Code</b></td>
<td><b>Line</b></td>
<td><b>Map Result</b></td>
</tr>
</thead>
<tbody>
@Html.EditorFor(m => m.TBMapBalances);
</tbody>
</table>
</div>
</div>
</div>
}
将你的“方法”、“控制器”放在(Html.BeginForm("TbMapViewEdit", "TbMap")) 中,否则表单 POST 操作将设置为当前位置。
型号
为简洁起见截断。我有一个带有列表的视图模型,我将把数据保存到另一个表中,只是为了显示一些信息。
public class TbMapViewModel
{
public IEnumerable<ASPNET_Core_1_0.Models.TBMapUniqueADP> TBMapUniqueADP { get; set; }
public List<TBMapBalances> TBMapBalances { get; set; } = new List<TBMapBalances>();
[...]
}
控制器
[Authorize]
[HttpPost]
public IActionResult TbMapViewEdit(TbMapViewModel tbMapViewModel)
{
if (ModelState.IsValid)
{
foreach (var TbListId in tbMapViewModel.TBMapBalances)
{
var getCode = _context.TBMapBalances.Where(p => p.TbMapId == TbListId.TbMapId).FirstOrDefault();
if (getCode != null)
{
getCode.UniqueAdp = TbListId.UniqueAdp;
}
}
_context.SaveChanges();
}
return RedirectToAction("TbMapView");
}
我在这里犯的错误是我试图用它自己的副本替换密钥(查找 ID 为 1 并将其设置为 ID 1),而不是选择我需要的实际字段编辑在我的例子中是 UniqueAdp。
然后给我带来了新的东西,那就是编辑器模板:
编辑器模板
在“视图”文件夹下的“共享”文件夹中创建一个名为 EditorTemplates 的文件夹,并使用您要编辑的模型的确切名称。在我的例子中,模型被称为TBMapBalances,所以我在新创建的文件夹中创建了一个TBMapBalances.cshtml 文件,然后粘贴了这个(这最初是在我的主视图文件中):
@model ASPNET_Core_1_0.Models.TBMapBalances
<tr>
<td>
@Html.DisplayFor(Model => Model.TbMapId)
@Html.HiddenFor(Model => Model.TbMapId)
</td>
<td>@Html.EditorFor(Model => Model.UniqueAdp, new { @class = "control-label_DI" })</td>
<td>@Html.DisplayFor(Model => Model.AccountsCode)</td>
<td>@Html.DisplayFor(Model => Model.Line)</td>
<td>@Html.DisplayFor(Model => Model.MapResult)</td>
</tr>
顺便说一句,new { @class = "control-label_DI" } 是为了给每个创建的输入字段添加类。这似乎在 .net 核心中不起作用,并留在那里只是为了提醒自己我需要以某种方式执行此操作。
研究:
Update multiple records at once in asp.net mvc
https://docs.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms
http://www.binaryintellect.net/articles/b1e0b153-47f4-4b29-8583-958aa22d9284.aspx
How to bind an Array in MVC Core
https://www.red-gate.com/simple-talk/dotnet/asp-net/model-binding-asp-net-core/
【问题讨论】:
标签: c# asp.net-core .net-core asp.net-core-mvc