Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从同一表单同时保存多行-dotnet core_C#_Asp.net Core_.net Core_Asp.net Core Mvc - Fatal编程技术网

C# 从同一表单同时保存多行-dotnet core

C# 从同一表单同时保存多行-dotnet core,c#,asp.net-core,.net-core,asp.net-core-mvc,C#,Asp.net Core,.net Core,Asp.net Core Mvc,我有一个表,其中有一个空列,用户可以在其中输入注释: Table ----- TbMapId | UniqueAdp | Dealership | Line -------------------------------------------------------------------- 1 | [Insert comment here] | Derby | abc123 2 |

我有一个表,其中有一个空列,用户可以在其中输入注释:

Table
-----

TbMapId |        UniqueAdp         |    Dealership    |    Line
--------------------------------------------------------------------
1       |    [Insert comment here] |    Derby         |    abc123
2       |    [Insert comment here] |    Keighley      |    cda345
3       |    [Insert comment here] |    Manchester    |    876ghj
有很多数据需要评论,我不能期望用户打开“编辑”页面并逐个输入评论。相反,我需要用户能够输入一堆评论(比如20行一次输入20条),并在点击提交按钮时保存所有评论


如果您想直接跳转到工作解决方案,请转到“编辑2”&查看鲁迪接受的答案


查看

        <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>
        <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 (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>
}
控制器:

这就是我需要帮助的地方,我的代码根本不会抛出任何错误。当我按Submit时,什么也没有发生:

        [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");
        }
编辑#2-拯救英雄-非常感谢@rudiviser的帮助

首先,如果你们中的任何一个像我一样被困在使用.NETCore1.0.0中 确保首先升级到最新版本(1.1.7 lts)。我的部分悲伤是因为我是一名用户1.0,没有升级我的安装,因为修复程序和附加程序不断出现。别做那个人,就像我

以下一切都要感谢鲁迪的帮助:

查看

        <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>
        <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 (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>
}
控制器

[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\u Core\u 1\u 0.Models.tbmap
@DisplayFor(Model=>Model.TbMapId)
@Html.HiddenFor(Model=>Model.TbMapId)
@EditorFor(Model=>Model.UniqueAdp,新的{@class=“control-label_DI”})
@DisplayFor(Model=>Model.AccountsCode)
@DisplayFor(Model=>Model.Line)
@DisplayFor(Model=>Model.MapResult)
顺便说一句,
新的{@class=“control-label_DI”}
应该是向每个创建的输入字段添加类的。这在.NETCore中似乎不起作用,留在那里只是为了提醒自己,我需要以某种方式这样做

研究:


您是否已经在razor页面中输入了注释?我没有看到他们。您要做的是创建一个表单,其中包含您希望循环中每个项目的输入类型。然后,每个表单将迭代器作为隐藏值引用,以便在发布时传递。如果循环是
foreach(Model.items中的var-item){}
,那么您将拥有一个表单,其中包含该块中的输入,并带有一个类似
的隐藏输入,这将允许您使用所需的任何标识符发布,以将特定表单数据附加到正确的模型


有关循环中表单的结构,请参见此答案。此问题有两个部分,第一部分是需要有一种方法来编辑数据集合。这可以通过EditorTemplates来解决,它涉及到创建一个编辑器模型,然后对要编辑的项集合调用
@Html.EditorFor(..)

最低限度的样本(完整的外汇,而不是核心)是可用的

第二个问题是实体更新的方式,更改的属性错误,因此没有保存(PK被更新为PK),并且实体在被跟踪时被附加

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;
}
当您从数据库检索模型时,记住实体框架为您做了什么是很重要的。它由上下文自动跟踪,因此它已附加并准备更新,您所更改的任何内容都将自动跟踪并随后保存

调用
\u context.Update(..)
尝试根据ID将未跟踪的模型(从发布的数据)附加到上下文,但因为您已经拉出了该ID(在
.Where(..).FirstOrDefault(..)
中),它已经被跟踪,因此爆炸了

另外,考虑到这是EFC 1.0,并且您没有
.Find(..)
方法,在主键字段上使用
.SingleOrDefault(..)
可能是更好的方法

您重写的代码可以是这样的:

foreach (var postedModel in tbMapViewModel.TBMapBalancesList)
{
    var dbModel = _context.TBMapBalances.SingleOrDefault(p => p.TbMapId == postedModel.TbMapId);
    if (dbModel != null)
    {
        dbModel.UniqueAdp = postedModel.UniqueAdp;
    }
}
await _context.SaveChangesAsync();
尽管出于安全原因,我不推荐给后代,但如果您想将整个发布模型附加到上下文(基于ID)并进行更新,可以使用与原始模型类似的代码,删除
foreach
循环:

_context.UpdateRange(tbMapViewModel.TBMapBalances);
await _context.SaveChangesAsync();
(我不建议这样做,因为发布的所有内容都将在数据库中进行设置,根据经验,建议只设置您希望根据第一个代码集更新的字段。但是,如果您不是从数据库加载并保存,则应该比foreach循环快,只保存后者)

@Html.EditorFor(Model=>Model.TBMapBalancesList[i].UniqueAdp,新的{@class=“control-label\u DI”})
这一行。HTML助手为数据库中的每个项目创建输入。您提到的逻辑已经存在,但是如果您阅读我的研究中的帖子,您会发现我到目前为止所做的似乎是正确的,我缺少的是controller中的POST action方法,或者更确切地说是如何让它再次将数据保存到TableThank。在我的编辑2中,我提到需要将核心框架和ef升级到最新版本。1.1.x中有“Find”。
foreach (var postedModel in tbMapViewModel.TBMapBalancesList)
{
    var dbModel = _context.TBMapBalances.SingleOrDefault(p => p.TbMapId == postedModel.TbMapId);
    if (dbModel != null)
    {
        dbModel.UniqueAdp = postedModel.UniqueAdp;
    }
}
await _context.SaveChangesAsync();
_context.UpdateRange(tbMapViewModel.TBMapBalances);
await _context.SaveChangesAsync();