原始问题: 这可能是一件简单的事情,但我已经寻找了 30 多个小时,但找不到任何适合我的答案(也尝试了很多方法)。
所以,我想要实现的是我必须在 View 上显示一些数据,并在同一 View 中获取一些值。为此,我创建了一个主视图,它显示一些数据并接受一些值。也是主视图中的部分 View ,它也显示一些数据并接受一些值。
主视图和部分 View 的模型不同,相关的数据库表也不同。
主视图模型:
public class VMBooking : VMBase
{
public int BookingID { get; set; }
public Guid BookingGUID { get; set; }
public int NoOfChildrenArrived { get; set; }
...
public List<VMBookingGuest> VMBookingGuests { get; set; }
...
}
部分 View 模型
public class VMBookingGuest
{
public int BookingGuestID { get; set; }
public int BookingID { get; set; }
public int GuestID { get; set; }
public string GuestName { get; set; }
public string GuestCNIC { get; set; }
public bool IsCNIC { get; set; }
public bool IsGuestArrived { get; set; }
public bool IsGuestDeparted { get; set; }
}
现在我已经成功地在局部 View 中传递了局部 View 模型,并且我的数据也正在显示..
我的主视图 CSHTML:
@using VMBooking
<form class="form-horizontal" id="validation-form" method="post" defaultbutton="btnSubmit">
@Html.HiddenFor(c => c.BookingID)
@Html.HiddenFor(c => c.BookingGUID)
@Html.Partial("_Arrival", Model.VMBookingGuests)
<div class="form-group">
<input asp-for="@Model.NoOfChildrenArrived" type="text" id="NoOfChildrenArrived" />
</div>
<button type="submit" id="btnSubmit">Submit</button>
</form>
部分 View CSHTML:
@foreach (var item in Model)
{
<tr class="center">
<td>@item.GuestName</td>
<td>@item.GuestCNIC</td>
<td>
<div>
<input id="IsGuestArrived" name="IsGuestArrived" asp-for="@item.IsGuestArrived" type="checkbox"/>
</div>
</td>
</tr>
}
对应的 Controller Action 如下
[HttpGet]
public IActionResult Arrival(int id)
{
VMBooking model = _BookingRepo.GetBookingByID(id);
model.VMBookingGuests = _BookingRepo.GetGuestinfo(id);
PopulateDropdowns(model);
return View(model);
}
[HttpPost]
public IActionResult Arrival(VMBooking vmBooking)
{
VMBooking model = _BookingRepo.GetBookingByID(vmBooking.BookingID);
model.VMBookingGuests = _BookingRepo.GetGuestinfo(vmBooking.BookingID);
if (model != null)
{
_BookingRepo.ArrivalUpdate(vmBooking);
foreach (var item in model.VMBookingGuests)
{
_BookingRepo.GuestArrivalUpdate(item);
}
return RedirectToAction("Index");
}
PopulateDropdowns(model);
return View();
}
一切工作正常,但问题出现了,我必须在主视图上的单个提交按钮上提交此组合输入数据(来自主视图和部分 View )。 当我按下提交按钮时,只有主视图中的值会传递到 Controller ,而不是部分 View 的值。
请注意,我必须将复选框值列表 (id="IsGuestArrived") 传递给每个访客条目的 Controller 。
正如之前所说,我尝试了多种不同的方法,但没有一个对我有用。所以我问,实现这一目标的合适方法是什么?
编辑: 我已经找到了我的查询的答案,现在我想显示我根据 @KingKing 的建议对代码所做的更改...
我所做的是在我的主视图中插入部分标记而不是@html.partial,所以我的主视图的代码如下
@using VMBooking
<form class="form-horizontal" id="validation-form" method="post" defaultbutton="btnSubmit">
@Html.HiddenFor(c => c.BookingID)
@Html.HiddenFor(c => c.BookingGUID)
<partial name="_Arrival" for="VMBookingGuests" />
<div class="form-group">
<input asp-for="@Model.NoOfChildrenArrived" type="text" id="NoOfChildrenArrived" />
</div>
<button type="submit" id="btnSubmit">Submit</button>
</form>
至于我的部分观点,我同意
@foreach (var item in Model)
{
<input type="hidden" asp-for="@Model[i].GuestID" />
<input type="hidden" asp-for="@Model[i].BookingID" />
<tr class="center">
<td>@item.GuestName</td>
<td>@item.GuestCNIC</td>
<td>
<div>
<input id="IsGuestArrived" name="IsGuestArrived" asp-for="@item.IsGuestArrived" type="checkbox"/>
</div>
</td>
</tr>
}
注意我在部分 View 中使用的隐藏值。
在我的 Controller 中而不是使用
model.VMBookingGuests = _BookingRepo.GetGuestinfo(vmBooking.BookingID);
我用过
model.VMBookingGuests = vmBooking.VMBookingGuests;
因为没有隐藏值,访客 ID 无法被识别。
最佳答案
在部分 View 中呈现的元素应该能够以其名称加上正确的路径前缀来呈现。 Html.Partial
有点棘手(最后会有解决方案)。但如果你使用标签助手 <partial>
,使用 for
会更容易属性(注意它与 model
属性不同,后者不会沿着当前名称路径传递),如下所示:
<partial name="_Arrival" for="VMBookingGuests"/>
您的部分 View 也需要更新,因为您正在映射一个数组,您需要使用索引来访问每个数组成员,以便每个项目的名称可以正确呈现(使用索引),如下所示:
<!-- NOTE: this requires the view model of your partial view must support accessing item by index, like an IList -->
@for(var i = 0; i < Model.Count; i++) {
<tr class="center">
<td>@Model[i].GuestName</td>
<td>@Model[i].GuestCNIC</td>
<td>
<div>
<input id="IsGuestArrived-@i" asp-for="@Model[i].IsGuestArrived" type="checkbox"/>
</div>
</td>
</tr>
}
现在它应该可以正常工作,因为元素名称已正确呈现,如 VMBookingGuests[0].IsGuestArrived
,...
现在为Html.Partial
,您仍然可以使用它,但您需要通过 ViewDataDictionary
传入前缀信息,您需要自己构建该前缀,但这很容易,因为我们只使用标准方法来获取它,如下所示:
@{
var vd = new ViewDataDictionary(ViewData);
vd.TemplateInfo.Prefix = Html.NameFor(e => e.VMBookingGuests);
}
<!-- for Html.Partial -->
@Html.Partial("_Arrival", Model.VMBookingGuests, vd)
现在,随着前缀信息的传递,元素名称也可以像使用 <partial>
时一样正确呈现。 。当然,您仍然需要为上面的部分 View 使用相同的更正代码。
关于c# - 当涉及不同模型时,如何将主视图和部分 View 值传递给 Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66992516/