我在控制器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);
查看部件如下所示:
@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;
答案 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; }
...