c# - 在 ASP.NET Core Razor 页面的集合中保存项目
问题描述
我不明白如何正确绑定集合中的单个项目。在我的项目中,学生可以使用以下模型制定多个计划:
public class Student
{
public Student()
{
Plans = new HashSet<Plan>();
}
public int StudentId { get; set; }
public string Designee { get; set; }
public string DesigneePhone { get; set; }
public virtual ICollection<Plan> Plans { get; set; }
}
public partial class Plan
{
public int PlanId { get; set; }
public int StudentId { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public virtual Student Student { get; set; }
}
我在页面上列出了每个计划都有自己的保存按钮。根据这篇 Learn Razor Pages 帖子,我认为我正确使用了 asp-for 助手。
@page "{studentId:int}"
@model CollectionTest.PlansModel
<form asp-page-handler="SaveMain" method="post">
<div class="row mt-3">
<input type="hidden" asp-for="Student.StudentId" />
<div class="col">
<label asp-for="Student.Designee"></label>
<input asp-for="Student.Designee" class="form-control" />
</div>
<div class="col">
<label asp-for="Student.DesigneePhone"></label>
<input asp-for="Student.DesigneePhone" class="form-control" />
</div>
<div class="col-auto align-self-end">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
</form>
<hr />
@for (int i = 0; i < Model.Student.Plans.Count(); i++)
{
var planId = Model.Student.Plans.ToList()[i].PlanId.ToString();
<div id="@("card_Plan" + planId)" class="card">
<div class="card-header">
<h5>Plan #@planId</h5>
</div>
<div class="card-body">
<form id="@("form_Plan" + planId)" asp-page-handler="SavePlan" method="post">
<input type="hidden" asp-for="Student.Plans.ToList()[i].PlanId" />
<div class="row">
<div class="col">
<label asp-for="Student.Plans.ToList()[i].StartDate"></label>
<input asp-for="Student.Plans.ToList()[i].StartDate" class="form-control" />
<span asp-validation-for="Student.Plans.ToList()[i].StartDate"></span>
</div>
<div class="col">
<label asp-for="Student.Plans.ToList()[i].EndDate"></label>
<input asp-for="Student.Plans.ToList()[i].EndDate" class="form-control" />
<span asp-validation-for="Student.Plans.ToList()[i].EndDate"></span>
</div>
</div>
</form>
</div>
<div class="card-footer">
<div class="float-right">
<button type="submit" class="btn btn-primary" form="@("form_Plan" + planId)">Save</button>
</div>
</div>
</div>
}
但似乎 SavePlan 页面处理程序中没有绑定任何内容:
[BindProperty]
public Student Student { get; set; }
.
.
.
public async Task<IActionResult> OnPostSavePlan(int planId)
{
if (!ModelState.IsValid)
{
return Page();
}
/******************************
*
* Student.Plans is empty and planId is zero
*
*******************************/
Plan plan = await _planContext.Plan.FirstAsync(p => p.PlanId == planId);
_planContext.Attach(plan).State = EntityState.Modified;
try
{
await _planContext.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!PlanExists(plan.PlanId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Plans");
}
我究竟做错了什么?
解决方案
根据您的代码,因为您在剃刀页面中传递的是[0].PlanId
,但您在 OnPostSavePlan 方法中收到的是planId
. 如果您只需要接收planId
,则需要更改表格。
<div class="card-body">
<form id="@("form_Plan" + planId)" asp-page-handler="SavePlan" method="post">
<input type="hidden" asp-for="@planId" />
根据您的要求,您似乎想通过一个计划列表。因此,您需要按以下步骤修改您的代码:
计划.cshtml:
<form id="form_Plan" asp-page-handler="SavePlan" method="post">
@for (int i = 0; i < Model.Student.Plans.Count(); i++)
{
var planId = Model.Student.Plans.ToList()[i].PlanId.ToString();
<div id="@("card_Plan" + planId)" class="card">
<div class="card-header">
<h5>Plan #@planId</h5>
</div>
<div class="card-body">
<input type="hidden" asp-for="Student.Plans.ToList()[i].PlanId" />
<div class="row">
<div class="col">
<label asp-for="Student.Plans.ToList()[i].StartDate"></label>
<input asp-for="Student.Plans.ToList()[i].StartDate" class="form-control" />
<span asp-validation-for="Student.Plans.ToList()[i].StartDate"></span>
</div>
<div class="col">
<label asp-for="Student.Plans.ToList()[i].EndDate"></label>
<input asp-for="Student.Plans.ToList()[i].EndDate" class="form-control" />
<span asp-validation-for="Student.Plans.ToList()[i].EndDate"></span>
</div>
</div>
</div>
</div>
}
<div class="card-footer">
<div class="float-right">
<button type="submit" class="btn btn-primary" form="form_Plan">Save</button>
</div>
</div>
</form>
计划.cshtml.cs:
public class PlansModel : PageModel
{
public IActionResult OnGet()
{
//for easy testing,I add the data manually
Student = new Student()
{
Plans = new List<Plan>()
{
new Plan(){ PlanId=1, StartDate=DateTime.Parse("2019-8-7")},
new Plan(){ PlanId=2, StartDate=DateTime.Parse("2019-4-7")},
new Plan(){ PlanId=3, StartDate=DateTime.Parse("2019-6-7")}
}
};
return Page();
}
[BindProperty]
public Student Student { get; set; }
public async Task<IActionResult> OnPostSavePlan(List<Plan> plans)
{
//...
}
}
更新:
计划.cshtml:
@foreach (var plan in Model.Student.Plans)
{
var planId = plan.PlanId.ToString();
<div id="@("card_Plan" + planId)" class="card">
<div class="card-header">
<h5>Plan #@planId</h5>
</div>
<div class="card-body">
<form id="@("form_Plan" + planId)" asp-page-handler="SavePlan" method="post">
<input type="hidden" asp-for="@plan.PlanId" />
<div class="row">
<div class="col">
<label asp-for="@plan.StartDate"></label>
<input asp-for="@plan.StartDate" class="form-control" />
<span asp-validation-for="@plan.StartDate"></span>
</div>
<div class="col">
<label asp-for="@plan.EndDate"></label>
<input asp-for="@plan.EndDate" class="form-control" />
<span asp-validation-for="@plan.EndDate"></span>
</div>
</div>
</form>
</div>
<div class="card-footer">
<div class="float-right">
<button type="submit" class="btn btn-primary" form="@("form_Plan" + planId)">Save</button>
</div>
</div>
</div>
}
计划.cshtml.cs:
public async Task<IActionResult> OnPostSavePlan(Plan plan)
{
//...
}
推荐阅读
- mysql - MYSQL更新具有重复值但最旧日期的行
- webpack - Webpack-Dev-Server 抛出 WDS 断开连接
- javascript - 仅当数据来自循环的 GET 请求时,JSON stringify 才会失败
- angular - 如何使用角度通过带有jwt令牌的rest调用下载文件
- python - Python:从多个创建输出 CSV。查找
- javascript - Angular 全局错误处理程序将 error.message 打印为错误本身
- python - 在 Python 中计算航空公司排名 - NameError: name is not defined
- elasticsearch - 如何在 Elasticsearch 输出脚本字段中访问 @metadata
- jsp - 将 servlet 转换为 Jax-RS Web 服务时如何替换隐式 pageContext 对象?
- php - php 序列化巨大的浮点数导致舍入和格式问题