aspnet核心如何从View发布数据,如果模型复杂

时间:2018-04-25 14:41:39

标签: c# jquery razor asp.net-core

我在控制器ASP.NET Core MVC中使用Post方法有一些问题。也许我使用错误的架构。

我有两个来自DB的模型。

     public class RecipeTable
    {
        public int Id { get; set; }
        public string MetrologyRecipe { get; set; }
        public string MetrologyTool { get; set; }
        //other properties
    }


    public class ParamTable
    {
        public int AupId { get; set; }
        public string ParamName{ get; set; }
        public string RecipeName { get; set; }
        public int? ParamOrderAuto { get; set; }
        //other properties
    }

为他们装箱子。因为RecipeTable中的一个条目与ParamTable的几个entre相关联。

 public class FullModel
{
    public List<ParamTable> ParamRows ;
    public RecipeTable RecipeRow { set; get; }

    public FullModel()
    {
        ParamRows = new List<ParamTable> ();
    }

}

对于[Get]&#34;编辑&#34;方法这很棒。

[HttpGet]
    public async Task<IActionResult> Edit(int? id, string recipeName)
    {
        var fullModel = new FullModel();
        if (id == null) return NotFound();


        fullModel.RecipeRow = await 
        _context.RecipeTable.SingleOrDefaultAsync(m => m.Id == id);


        foreach (var row in _context.ParamTable)
            if (recipeName == row.RecipeName)
               fullModel.ParamRows.Add(row);



        if (fullModel.RecipeRow.MetrologyRecipe == null) return NotFound();
        return View(fullModel);
    }

但对于[Post]&#34;编辑&#34;当然,这是行不通的。 仅配方部件已更新。我不明白post方法如何从View获取数据。当您无法更改数据库时,如何使用这些复杂的模型,并且无法使用 直接在数据库设计器中指定连接。

 [HttpPost, ActionName("Edit")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, FullModel fullModel)
    {
        if (id != fullModel.RecipeRow.Id) return NotFound();

        if (ModelState.IsValid)
        {
            try
            {
                //**Here fullModel.ParamRows.Count = 0**
                _context.Update(fullModel.RecipeRow);
                await _context.SaveChangesAsync();
                foreach (var elem in fullModel.ParamRows)
                {
                    _context.Update(elem);
                    await _context.SaveChangesAsync();
                }

            }
            catch (DbUpdateConcurrencyException)
            {
                if (!RecipeTableExists(fullModel.RecipeRow.Id))
                    return NotFound();
                throw;
            }

            return RedirectToAction(nameof(Index));
        }

        return View(fullModel);

查看部件如下所示:

&#13;
&#13;
@model FullModel

@{
    ViewData["Title"] = "Edit";
}

<div class="row">
    <div class="col-md-4">
        <form asp-action="Edit">
          

 <table class="table" style="margin-left: -50px">
                <thead>
                    <tr>
                        <th>Order</th>
                        <th>Param</th>
                    </tr>
                </thead>
                  <tbody>
                    @for (var i = 0; i < Model.ParamRows.Count; i++)
                    {
                        <tr>
                            <td>
                                <div class="form-group">
                                    <input asp-for="@Model.ParamRows[i].ParamOrderAuto" type="text" class="form-control" />
                                </div>
                            </td>
                            <td>
                                <div class="form-group">
                                    <input  asp-for="@Model.ParamRows[i].ParamName" class="form-control" />
                                </div>
                            </td>
                         </tr>
                          }

                </tbody>
            </table>

            <div class="form-group">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

您无法使用foreach来迭代ParamRows。为了使模型绑定器能够将其绑定回帖子上的列表,字段需要具有ParamRows[N].ParamName之类的名称。使用foreach,您最终会得到row.ParamName之类的名称,而模型绑定器将无法识别这些名称,只会丢弃。

相反,请使用标准for循环:

@for (var i = 0; i < Model.ParamRows.Count; i++)
{
    ...
    <input asp-for="ParamRows[i].ParamName" />
    ...
}

或者,您可以为ParamTable创建一个编辑器模板,即~/Views/Shared/EditorTemplates/ParamTable.cshtml,并将所有HTML(字段,标签等)用于编辑ParamTable实例。 。然后,您可以简单地执行:

,而不是遍历ParamRows中的项目
@Html.EditorFor(m => m.ParamRows)

Razor将自动遍历每个项目并为每个项目呈现编辑器模板,为每个字段提供正确的绑定名称。

答案 1 :(得分:0)

FullModel您遇到一个小问题,需要添加get; set;方法。就这样纠正:

public class FullModel
{
    public List<ParamTable> ParamRows { get; set; };
    public RecipeTable RecipeRow { set; get; }
...