【问题标题】:How do I use two different models in one view?如何在一个视图中使用两种不同的模型?
【发布时间】:2020-11-12 12:00:56
【问题描述】:

我目前正在使用 MVC 2.1 进行编程,但遇到了问题。我的主要视图是使用模型 IEnumerable 显示成员列表。我想在该页面上有一个表单,单击该表单时将填充所选成员的信息。为此,我需要从特定的成员实例中提取数据。

我有这个功能使用不同的视图,但我想知道是否可以只使用一个视图。

【问题讨论】:

  • 开始阅读 ViewModels。
  • @mason 抱歉,是的,我使用的是 ASP.net core 2.1
  • 我已经适当地重新标记了您的问题。名称中缺少“core”的标签是针对旧的基于 .NET Framework 的 ASP.NET 平台,以及在其上运行的旧 MVC 框架。
  • 您能否提供更多关于“我需要从特定成员实例中提取数据”的信息?

标签: c# asp.net-core asp.net-core-mvc


【解决方案1】:

最简单的设计是创建一个包含成员集合和成员模型的视图模型。在 html 页面上单击成员名称后,您的表单将提交成员的标识符(例如名称),接收操作将返回包含成员集合的模型并填充成员模型。看看下面的模型:

public class MyViewModel
{
    public IEnumerable<string> MembersList { get; set; }
    public Member Member { get; set; }
}

public class Member
{
    public string MemberName { get; set; }
    public string MemberId { get; set; }
}

在你的控制器中,你应该有一个类似这样的动作:

[Post]
public IActionResult Index(string memberName)
{
    //Maybe add some validation.
    
    MyViewModel model = new()
    {
        MembersList = MethodThatPopulatesTheMembers(),
        Member = MethodThatGetsTheMemberByMemberName(memberName)
    };

    return View(model);
}

顺便说一句,您将在页面初始显示期间遇到空引用错误,如果成员为空(即您的方法找不到具有该名称的成员,因为您在编程时出错或成员被删除) .为了解决这个问题,您可以为您的 Member 对象创建一个新实例,或者如果它为 null,则隐藏绑定到 Member 模型的 html 字段。

一旦您对同步页面请求更加熟悉,请考虑练习异步页面请求。你可能想看看fetch

【讨论】:

    【解决方案2】:

    我想在该页面上有一个表单,该表单将填充 单击时选择成员的信息。为此,我会 需要从特定的成员实例中提取数据。

    根据您的描述,成员和成员信息表应包含relationship(一对一或一对多)。在点击选中的成员时显示成员的信息,我觉得最好用JQuery ajax来实现。

    尝试在行中添加一个“详细信息”按钮,单击它时,使用 JQuery ajax 获取所选成员的信息(基于 MemberID 属性)。您可以参考以下示例:

    1. 创建Member和MemberInformation类并配置关系(假设它包含一对一关系):

       public class Member
       {
           public int MemberID { get; set; }
           public string Name { get; set; }
           public string Email { get; set; }
           public string Password { get; set; }
      
           public MemberInformation MemberInformation { get; set; }
       }
      
       public class MemberInformation {
           public int  ID  { get; set; }
           public string Address { get; set; }
           public DateTime BirthDate { get; set; }
           public string City { get; set; }
      
           [ForeignKey("Member")]
           public int MemberID { get; set; }
           public Member Member { get; set; }
       }
      
    2. 创建控制器动作方法:

       // GET: Members
       public async Task<IActionResult> Index()
       {  
           return View(await _context.Members.ToListAsync());
       }
       //get the MemberInformation based on the MemberId
       [HttpPost]
       public JsonResult GetMemberInformation(int memberid)
       {
           return Json(_context.MemberInformation.Where(c => c.MemberID == Convert.ToInt32(memberid)).FirstOrDefault());
       }
      
    3. 创建主视图:

      在查看页面中,显示会员后,添加一个表格来显示所选会员的信息。然后,使用jquery查找选中的Memberid,并根据该值使用Ajax方法获取该成员的信息。

           @model IEnumerable<netcore2_1.Models.Member>
      
           @{
               ViewData["Title"] = "Index";
           }
      
           <h2>Index</h2>
           <p><a asp-action="Create">Create New</a></p>
           <table class="table">
               <thead>
                   <tr>
                       <th>
                           @Html.DisplayNameFor(model => model.Name)
                       </th>
                       <th>
                           @Html.DisplayNameFor(model => model.Email)
                       </th>
                       <th></th>
                   </tr>
               </thead>
               <tbody>
           @foreach (var item in Model) {
                   <tr>
                       <td>
                           @Html.DisplayFor(modelItem => item.Name)
                       </td>
                       <td>
                           @Html.DisplayFor(modelItem => item.Email)
                       </td>
                       <td> 
                           <a asp-action="Details" class="link_detail" data-memberid="@item.MemberID" asp-route-id="@item.MemberID">Details</a>  
                       </td>
                   </tr>
           }
               </tbody>
           </table>
      
           <div>
               <h2>Member Information</h2>
               <div id="memberinfo">
                   <form asp-action="DisplayMemberInformation"> 
                       <input type="hidden" id="memberinfoid" name="ID" />
                       <div class="form-group">
                           <label for="Address" class="control-label">Address</label>
                           <input id="txtaddress" name="Address" class="form-control" /> 
                       </div>
                       <div class="form-group">
                           <label for="BirthDate" class="control-label">BirthDate</label>
                           <input id="txtBirthdate" name="BirthDate" class="form-control" /> 
                       </div>
                       <div class="form-group">
                           <label for="City" class="control-label">City</label>
                           <input id="txtCity" name="City" class="form-control" /> 
                       </div> 
                       <div class="form-group">
                           <input type="submit" value="Save" class="btn btn-default" />
                       </div>
                   </form>
               </div> 
           </div>
      
           @section Scripts{ 
               <script src="~/lib/jquery/dist/jquery.js"></script>
               <script type="text/javascript">
                   $(function () {
                       $(".link_detail").each(function (index, item) {
                           $(item).click(function () {
                               event.preventDefault();  //prevent the default event.
                               //get the selected memberid.
                               var memberid = parseInt($(this).attr("data-memberid")); 
                               $.ajax({
                                   type: "POST",
                                   url: "/Members/GetMemberInformation",
                                   data: { memberid: memberid }, 
                                   success: function (data) {
                                       //populate the Form.
                                       $("#memberinfoid").val(data.ID);
                                       $("#txtaddress").val(data.Address);
                                       $("#txtBirthdate").val(data.BirthDate);
                                       $("#txtCity").val(data.City);
                                   },
                                   failure: function (response) {
                                       console.log(response.responseText);
                                   },
                                   error: function (response) {
                                       console.log(response.responseText);
                                   }
                               });
      
                           });
                       }); 
                   });
               </script>
           }
      

    结果如下:

    此外,您还可以使用分部视图显示会员信息,并使用 JQuery Ajax 动态将分部视图添加到主视图。

    创建局部视图:

        @model netcore2_1.Models.MemberInformation
    
        <h4>MemberInformation</h4>
        <hr />
        <div class="row">
            <div class="col-md-4">
                <form asp-action="DisplayMemberInformation">
                    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                    <input type="hidden" asp-for="ID" />
                    <div class="form-group">
                        <label asp-for="Address" class="control-label"></label>
                        <input asp-for="Address" class="form-control" />
                        <span asp-validation-for="Address" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="BirthDate" class="control-label"></label>
                        <input asp-for="BirthDate" class="form-control" />
                        <span asp-validation-for="BirthDate" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="City" class="control-label"></label>
                        <input asp-for="City" class="form-control" />
                        <span asp-validation-for="City" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="MemberID" class="control-label"></label>
                        <input asp-for="MemberID" readonly class="form-control" />
                        <span asp-validation-for="MemberID" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <input type="submit" value="Save" class="btn btn-default" />
                    </div>
                </form>
            </div>
        </div>
    

    添加DisplayMemberInformation方法:使用JQuery Ajax调用该方法并显示成员信息。

        [HttpPost]
        public IActionResult DisplayMemberInformation(int memberid)
        {
            var memberinfo = _context.MemberInformation.Where(c => c.MemberID == memberid).Select(c => c).FirstOrDefault();
            return PartialView("DisplayMemberInformation", memberinfo);
        }
    

    主视图中的代码:

            @model IEnumerable<netcore2_1.Models.Member> 
            @{  ViewData["Title"] = "Index"; } 
            <h2>Index</h2> 
            <p> <a asp-action="Create">Create New</a></p>
            <table class="table">
                <thead>
                    <tr>
                        <th> @Html.DisplayNameFor(model => model.Name) </th>
                        <th> @Html.DisplayNameFor(model => model.Email) </th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
            @foreach (var item in Model) {
                    <tr>
                        <td> @Html.DisplayFor(modelItem => item.Name) </td>
                        <td> @Html.DisplayFor(modelItem => item.Email) </td>
                        <td> 
                            <a asp-action="Details" class="link_detail" data-memberid="@item.MemberID" asp-route-id="@item.MemberID">Details</a>  
                        </td>
                    </tr>
            }
                </tbody>
            </table>
    
                <div id="partial_info">
    
                </div> 
    
            @section Scripts{ 
                <script src="~/lib/jquery/dist/jquery.js"></script>
                <script type="text/javascript">
                    $(function () { 
                        $(".link_detail").each(function (index, item) {
                            $(item).click(function () {
                                event.preventDefault();
                                var memberid = parseInt($(this).attr("data-memberid"));
                                $.ajax({
                                    type: "POST",
                                    url: "/Members/DisplayMemberInformation",
                                    data: { memberid: memberid },
                                    success: function (data) {
                                        //populate the Form. 
                                        $("#partial_info").html("");
                                        $("#partial_info").append(data);
                                    }, 
                                    error: function (response) {
                                        console.log(response.responseText);
                                    }
                                });
    
                            });
                        });
                    });
                </script>
            }
    

    最后,如果您想在主视图中直接显示多个对象,您可以尝试创建一个包含多个对象的 ViewModel,然后在主视图中显示该 ViewModel。或者,您可以使用 ViewBag 或 ViewData。更多详细信息,请查看Passing data to views

    此外,如果这些对象包含关系,请尝试引用Read related data - ASP.NET MVC with EF Core

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      • 2018-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多