ASP.NET Core 3.1 Razor 页面:复杂模型绑定

问题描述 投票:0回答:2

我正在努力处理数据绑定和 Razor 页面。我想要一个页面来创建预订,以收集所有必要的数据,以便在一切完成后将其发布到 Web 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>

是否可以在一页上完成所有这些操作,或者我应该朝不同的方向进行?

c# asp.net-core razor-pages asp.net-core-3.1
2个回答
0
投票

这里是添加和删除 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();
        }
    }

结果:


0
投票

在你的问题中,有几个概念我也很难理解。

您遇到的第一个问题是在 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。

我相信您将能够从这里弄清楚其余的功能。

© www.soinside.com 2019 - 2024. All rights reserved.