c# - 当涉及不同模型时,如何将主视图和部分 View 值传递给 Controller ​​?

标签 c# asp.net-mvc asp.net-core partial-views pass-data

原始问题: 这可能是一件简单的事情,但我已经寻找了 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/

相关文章:

c# - 带有 ByRef 的 COM Interop 方法签名

asp.net-mvc - 小写网址和尾部斜杠

php - MVC Web 应用程序中的 Controller 应该是可单元测试的吗?

asp.net-mvc - Web API 模型绑定(bind)器不适用于 HttpPostedFileBase?

c# - 未处理的异常。 System.ArgumentNullException : Value cannot be null.(参数 'path1' )在 System.IO.Path.Combine(字符串路径1,字符串路径2)

asp.net-core - 如何使用 Azure Active Directory 在 ASP.NET Core 应用程序中获取经过身份验证的用户的名称

c# - LINQ - 在 IEnumerable 中选择第二个项目

C# 在 Release 模式下运行时是否会编译出 Debug 语句?

c# - 如何在 App.Config 中写入 URI 字符串

sql-server - .NET Core 中错误 "Must declare the scalar variable @ "的含义是什么