Asp .Net Core 3.1 Razor 页面:复杂模型绑定
Asp .Net Core 3.1 Razor Page: Complex model binding
我正在为数据绑定和 Razor 页面苦苦挣扎
我找不到解决方案。可能我问的问题不对。
所以我希望你能帮我指出正确的方向。
我想要一个页面来创建预订以收集所有必要的数据,以便 post 将其上传到网络 api 一切都完成后。
在那个页面上,我想收集预订所需的数据,并想在预订中添加 x 个预订详细信息。
数据模型
public class Booking
{
[Key]
public int Id { get; set; }
public string Reference { get; set; }
public List<BookingDetail> BookingDetails { get; set; }
}
public class BookingDetail
{
[Key]
public int Id { get; set; }
public int Pieces { get; set; }
public string Marks { get; set; }
}
我想做的是为预订创建一个创建页面。
到目前为止,我已按照此说明进行操作 Link
缺少的部分是我想在同一个 Razor 页面上添加新的预订详细信息。
所以我想查看所有添加的预订详细信息的列表,并且我希望有文本框来添加新的预订详细信息。
我的想法是执行以下操作,但我收到 System.NullReferenceException
预订为空:
@page
@model Onlinebooking.Web.Pages.BookingModel
@{
ViewData["Title"] = "Booking";
}
<h1>Booking4</h1>
<form method="post">
Reference: <Input asp-for="Booking.Reference" /><br />
Pieces: <input asp-for="Booking.BookingDetails[0].Pieces" /><br />
Marks: <input asp-for="Booking.BookingDetails[0].Marks" /><br />
<br />
<input type="submit" value="submit" />
</form>
<form method="post" asp-page-handler="DeleteBookingDetails">
@for (var i = 0; i < @Model.Booking.BookingDetails.Count(); i++)
{
@Html.LabelFor(x => x.Booking.BookingDetails[i].Pieces)
@Html.LabelFor(x => x.Booking.BookingDetails[i].Marks)
}
</form>
是否可以在一页上完成所有这些工作,还是我应该换个方向?
感谢您的帮助!
在你的问题中,有几个概念我也很难理解。
您遇到的第一个问题是在 CSHTML.CS 文件中。初始化您的变量将解决该问题。
public class BookingModel : PageModel
{
private readonly DataDbContext _context;
public BookingModel(DataDbContext context)
{
_context = context;
}
public List<Booking> Bookings { get; set; } = new List<Booking>();
public Booking Booking { get; set; } = new Booking();
public BookingDetail BookingDetail { get; set; } = new BookingDetail();
public void OnGet()
{
Bookings = _context.Bookings.Include(x => x.BookingDetails).ToList();
}
}
在 CSHTML 方面,我会稍微修改您引用标签和打印 FOR 循环的方式。
<form method="post" asp-page-handler="DeleteBookingDetails">
<table>
<thead>
<tr>
<th><label asp-for="BookingDetail.Pieces" class="control-label"></label></th>
<th><label asp-for="BookingDetail.Marks" class="control-label"></label></th>
</tr>
</thead>
<tbody>
@foreach (var booking in Model.Bookings)
{
foreach (var bookingDetail in booking.BookingDetails)
{
<tr>
<td>@bookingDetail.Pieces</td>
<td>@bookingDetail.Marks</td>
</tr>
}
}
</tbody>
</table>
我没有修改 Booking 或 BookingDetail。
我相信您将能够从这里找出其余的功能。
这里是添加和删除BookingDetai的演示:
cshtml:
<form method="post">
<Input asp-for="Booking.Id" hidden />
Reference: <Input asp-for="Booking.Reference" /><br />
Pieces: <input name="Booking.BookingDetails[@Model.Booking.BookingDetails.Count()].Pieces" /><br />
Marks: <input name="Booking.BookingDetails[@Model.Booking.BookingDetails.Count()].Marks" /><br />
<br />
<input type="submit" value="submit" asp-page-handler="AddBookingDetails"/>
<div hidden>
@for (var i = 0; i < @Model.Booking.BookingDetails.Count(); i++)
{
<input asp-for="@Model.Booking.BookingDetails[i].Id" hidden />
<input asp-for="@Model.Booking.BookingDetails[i].Pieces" hidden />
<input asp-for="@Model.Booking.BookingDetails[i].Marks" hidden />
}
</div>
</form>
<table>
<thead>
<tr>
<th><label class="control-label">Pieces</label></th>
<th><label class="control-label">Marks</label></th>
<th><label class="control-label">Action</label></th>
</tr>
</thead>
<tbody>
@for (var i = 0; i < @Model.Booking.BookingDetails.Count(); i++)
{
<tr>
<form method="post" >
<div hidden>
@for (var j = 0; j < @Model.Booking.BookingDetails.Count(); j++)
{
<input asp-for="@Model.Booking.BookingDetails[j].Id" hidden />
<input asp-for="@Model.Booking.BookingDetails[j].Pieces" hidden />
<input asp-for="@Model.Booking.BookingDetails[j].Marks" hidden />
}
</div>
<td>@Model.Booking.BookingDetails[i].Pieces</td>
<input name="Booking.Id" hidden value="@Model.Booking.Id" />
<input name="Booking.Reference" hidden value="@Model.Booking.Reference" />
<input name="BookingDetail.Id" hidden value="@Model.Booking.BookingDetails[i].Id" />
<td>@Model.Booking.BookingDetails[i].Marks</td>
<td><button asp-page-handler="DeleteBookingDetails">delete</button></td>
</form>
</tr>
}
</tbody>
</table>
cshtml.cs(我用简单的数据来测试):
public class CreateBookingModel : PageModel
{
[BindProperty]
public Booking Booking { get; set; }
[BindProperty]
//BookingDetail is used to delete BookingDetail
public BookingDetail BookingDetail { get; set; }
public static int count;
public ActionResult OnGet()
{
List<BookingDetail> list = new List<BookingDetail> { new BookingDetail { Id = 1, Pieces = 2, Marks = "m1" }, new BookingDetail { Id = 2, Pieces = 1, Marks = "m2" } };
Booking = new Booking { Id = 1, Reference = "r", BookingDetails = list };
count = 2;
return Page();
}
public ActionResult OnPostAddBookingDetails() {
Booking.BookingDetails[Booking.BookingDetails.Count()-1].Id = ++count;
return Page();
}
public ActionResult OnPostDeleteBookingDetails() {
Booking.BookingDetails.RemoveAll(b => b.Id == BookingDetail.Id);
return Page();
}
}
结果:
我正在为数据绑定和 Razor 页面苦苦挣扎
我找不到解决方案。可能我问的问题不对。 所以我希望你能帮我指出正确的方向。
我想要一个页面来创建预订以收集所有必要的数据,以便 post 将其上传到网络 api 一切都完成后。
在那个页面上,我想收集预订所需的数据,并想在预订中添加 x 个预订详细信息。
数据模型
public class Booking
{
[Key]
public int Id { get; set; }
public string Reference { get; set; }
public List<BookingDetail> BookingDetails { get; set; }
}
public class BookingDetail
{
[Key]
public int Id { get; set; }
public int Pieces { get; set; }
public string Marks { get; set; }
}
我想做的是为预订创建一个创建页面。 到目前为止,我已按照此说明进行操作 Link
缺少的部分是我想在同一个 Razor 页面上添加新的预订详细信息。
所以我想查看所有添加的预订详细信息的列表,并且我希望有文本框来添加新的预订详细信息。
我的想法是执行以下操作,但我收到 System.NullReferenceException
预订为空:
@page
@model Onlinebooking.Web.Pages.BookingModel
@{
ViewData["Title"] = "Booking";
}
<h1>Booking4</h1>
<form method="post">
Reference: <Input asp-for="Booking.Reference" /><br />
Pieces: <input asp-for="Booking.BookingDetails[0].Pieces" /><br />
Marks: <input asp-for="Booking.BookingDetails[0].Marks" /><br />
<br />
<input type="submit" value="submit" />
</form>
<form method="post" asp-page-handler="DeleteBookingDetails">
@for (var i = 0; i < @Model.Booking.BookingDetails.Count(); i++)
{
@Html.LabelFor(x => x.Booking.BookingDetails[i].Pieces)
@Html.LabelFor(x => x.Booking.BookingDetails[i].Marks)
}
</form>
是否可以在一页上完成所有这些工作,还是我应该换个方向?
感谢您的帮助!
在你的问题中,有几个概念我也很难理解。
您遇到的第一个问题是在 CSHTML.CS 文件中。初始化您的变量将解决该问题。
public class BookingModel : PageModel
{
private readonly DataDbContext _context;
public BookingModel(DataDbContext context)
{
_context = context;
}
public List<Booking> Bookings { get; set; } = new List<Booking>();
public Booking Booking { get; set; } = new Booking();
public BookingDetail BookingDetail { get; set; } = new BookingDetail();
public void OnGet()
{
Bookings = _context.Bookings.Include(x => x.BookingDetails).ToList();
}
}
在 CSHTML 方面,我会稍微修改您引用标签和打印 FOR 循环的方式。
<form method="post" asp-page-handler="DeleteBookingDetails">
<table>
<thead>
<tr>
<th><label asp-for="BookingDetail.Pieces" class="control-label"></label></th>
<th><label asp-for="BookingDetail.Marks" class="control-label"></label></th>
</tr>
</thead>
<tbody>
@foreach (var booking in Model.Bookings)
{
foreach (var bookingDetail in booking.BookingDetails)
{
<tr>
<td>@bookingDetail.Pieces</td>
<td>@bookingDetail.Marks</td>
</tr>
}
}
</tbody>
</table>
我没有修改 Booking 或 BookingDetail。
我相信您将能够从这里找出其余的功能。
这里是添加和删除BookingDetai的演示:
cshtml:
<form method="post">
<Input asp-for="Booking.Id" hidden />
Reference: <Input asp-for="Booking.Reference" /><br />
Pieces: <input name="Booking.BookingDetails[@Model.Booking.BookingDetails.Count()].Pieces" /><br />
Marks: <input name="Booking.BookingDetails[@Model.Booking.BookingDetails.Count()].Marks" /><br />
<br />
<input type="submit" value="submit" asp-page-handler="AddBookingDetails"/>
<div hidden>
@for (var i = 0; i < @Model.Booking.BookingDetails.Count(); i++)
{
<input asp-for="@Model.Booking.BookingDetails[i].Id" hidden />
<input asp-for="@Model.Booking.BookingDetails[i].Pieces" hidden />
<input asp-for="@Model.Booking.BookingDetails[i].Marks" hidden />
}
</div>
</form>
<table>
<thead>
<tr>
<th><label class="control-label">Pieces</label></th>
<th><label class="control-label">Marks</label></th>
<th><label class="control-label">Action</label></th>
</tr>
</thead>
<tbody>
@for (var i = 0; i < @Model.Booking.BookingDetails.Count(); i++)
{
<tr>
<form method="post" >
<div hidden>
@for (var j = 0; j < @Model.Booking.BookingDetails.Count(); j++)
{
<input asp-for="@Model.Booking.BookingDetails[j].Id" hidden />
<input asp-for="@Model.Booking.BookingDetails[j].Pieces" hidden />
<input asp-for="@Model.Booking.BookingDetails[j].Marks" hidden />
}
</div>
<td>@Model.Booking.BookingDetails[i].Pieces</td>
<input name="Booking.Id" hidden value="@Model.Booking.Id" />
<input name="Booking.Reference" hidden value="@Model.Booking.Reference" />
<input name="BookingDetail.Id" hidden value="@Model.Booking.BookingDetails[i].Id" />
<td>@Model.Booking.BookingDetails[i].Marks</td>
<td><button asp-page-handler="DeleteBookingDetails">delete</button></td>
</form>
</tr>
}
</tbody>
</table>
cshtml.cs(我用简单的数据来测试):
public class CreateBookingModel : PageModel
{
[BindProperty]
public Booking Booking { get; set; }
[BindProperty]
//BookingDetail is used to delete BookingDetail
public BookingDetail BookingDetail { get; set; }
public static int count;
public ActionResult OnGet()
{
List<BookingDetail> list = new List<BookingDetail> { new BookingDetail { Id = 1, Pieces = 2, Marks = "m1" }, new BookingDetail { Id = 2, Pieces = 1, Marks = "m2" } };
Booking = new Booking { Id = 1, Reference = "r", BookingDetails = list };
count = 2;
return Page();
}
public ActionResult OnPostAddBookingDetails() {
Booking.BookingDetails[Booking.BookingDetails.Count()-1].Id = ++count;
return Page();
}
public ActionResult OnPostDeleteBookingDetails() {
Booking.BookingDetails.RemoveAll(b => b.Id == BookingDetail.Id);
return Page();
}
}
结果: