Asp .Net Core 3.1 Razor页面:复杂模型绑定

时间:2020-07-27 14:49:14

标签: c# asp.net-core razor asp.net-core-3.1 asp.net-core-razor-pages

我正在努力处理数据绑定和Razor页面

我找不到解决方案。大概我问的不是正确的问题。 因此,希望您能帮助我指出正确的方向。

我希望页面创建预订以收集所有必要的数据,以便在完成所有操作后将其发布到网络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

缺少的部分是,我也想在同一剃刀页面上添加新的预订详细信息。

所以我想查看所有已添加的预订详细信息的列表,并且希望有文本框来添加新的预订详细信息。

我的想法是执行以下操作,但由于预订为空,因此我收到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>

是否甚至可以在一页上完成所有操作,还是应该朝不同的方向前进?

感谢您的帮助!

2 个答案:

答案 0 :(得分: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。

我相信您可以从这里了解其余功能。

答案 1 :(得分: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();
        }
    }

结果: enter image description here