使用IEnumerable在一个视图中使用多个模型

时间:2014-04-10 10:38:41

标签: c# asp.net asp.net-mvc asp.net-mvc-4 razor

问题陈述: 我想创建一个视图,首先我接受两个参数作为从日期和日期开始,还有一个基于哪个索引的下拉列表,以显示与组合框中所选项目相对应的所有细节。

为此,我定义了两个模型: 第一个模型包括从前端插入的参数,再次在第二个模型中,我定义了在该页面的索引中显示所需的所有参数。

这是我的模型

public class SearchModel
    {
        [Required]
        [Display(Name = "From Date")]
        public DateTime FromDate { get; set; }

        [Required]
        [Display(Name = "To Date")]
        public DateTime ToDate { get; set; }

        [Display(Name = "Search #")]
        public String SearchNumber { get; set; }
    }

 public class IndexModel
    {
        [Required]
        [Display(Name = "Search #")]
        public string SearchNumber { get; set; }

        [Key]
        [Required]
        [Display(Name = "SearchID")]
        public int SearchID{ get; set; }

        [Display(Name = "Received Date")]
        public DateTime ReceivedDate { get; set; }
}

最后,我将全局模型中的两个模型定义为:

public class GlobalModel
    {
        public SearchModel SearchModel { get; set; }
        public IndexModel IndexModel { get; set; }
    }

最后,当我尝试使用GlobalModel作为

在索引中的视图中编写代码时
@model IEnumerable<...SomePath.GlobalModel>  

@{
    ViewBag.Title = "Index";
}
<div style="padding-left: 40%">
        @using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))
        {
            @Html.AntiForgeryToken()
            @Html.ValidationSummary(true)

            <fieldset>
                <legend>Search</legend>
                  <ol>
                    <li>

                        <div class="editor-label">
                            @Html.LabelFor(model => model.SearchModel.FromDate)
                        </div>
                        <div class="editor-field">
                            @Html.EditorFor(model => model.SearchModel.FromDate)
                            @Html.ValidationMessageFor(model => model.SearchModel.FromDate)
                        </div>
                    </li>
                    <li>
                          <div class="editor-label">
                            @Html.LabelFor(model => model.SearchModel.ToDate)
                        </div>
                        <div class="editor-field">
                            @Html.EditorFor(model => model.SearchModel.ToDate)
                            @Html.ValidationMessageFor(model => model.SearchModel.ToDate)
                        </div>
                    </li>
                    <li>
                        @Html.DropDownListFor(model => model.SearchModel.SearchNumber, new SelectList(Model.ddlSearchNo.ddlSearchNumber, "Value", "Text"), "Select Search #", new { id="SearchID",onchange="GetSearchNo()" })
                        @Html.ValidationMessageFor(model => model.FirstOrDefault().SearchModel.SearchNumber)
                    </li>
                </ol>
               </fieldset>

        }
    </div>

<div>
    <table style="border-collapse: separate; border-spacing: 15px;">
    <tr>
        <th style="text-align:center;">
            @Html.DisplayNameFor(model => model.IndexModel.SearchNumber)
        </th>
        <th style="text-align:center;">
            @Html.DisplayNameFor(model => model.IndexModel.SearchID)
        </th>
        <th style="text-align:center;">
            @Html.DisplayNameFor(model => model.IndexModel.ReceivedDate)
        </th>

       </tr>

@foreach (var item in Model) {
    <tr>
        <td style="text-align:center;">
            @Html.DisplayFor(modelItem => item.IndexModel.SearchNumber)
        </td>
       <td style="text-align:center;">
            @Html.DisplayFor(modelItem => item.IndexModel.SearchID)
        </td>

        <td style="text-align:center;">
            @Html.DisplayFor(modelItem => item.IndexModel.ReceivedDate)
        </td>

        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.IndexModel.SearchID}) |
            @Html.ActionLink("Details", "Details", new{id=item.Model.SearchID}) |
            @Html.ActionLink("Delete", "Delete", new {id=item.IndexModel.SearchID })
        </td>
    </tr>
}

</table>

</div>

在这里,虽然我在顶部使用全局模型名称并且使用全局模型的对象,但我试图访问子模型的参数但是我得到的错误就像没有 声明或无法识别。

如果我使用某人建议的FirstorDefault(),我可以访问子模型的所有参数:

@Html.LabelFor(model => model.FirstorDefault().SearchModel.FromDate)

但在加载时会抛出异常,因为值不能为空。

如果我不在顶部使用Ienumerable,那么我在foreach循环中得到错误。

我也发现在stackoverflow中我需要在父模型中定义子模型时使用Ienumerable:

public IEnumerable<SearchModel> SearchModel { get; set; }
        public IEnumerable<IndexModel> IndexModel { get; set; }

但是还有其他一些错误。

我只是想加载我的观点,即使经过大量的尝试和研究,我也无法做到这一点。 我应该做些什么改变......?

任何帮助都将不胜感激。

在控制器索引操作方法中,我编写了代码:

 public ActionResult Index()
        {
            var result = GetDetails();
            return View(result); 
        }

我的方法是:

 public IEnumerable<GlobalModel> GetDetails()
        {
            return (from po in dbEntity.SearchDetails.AsEnumerable()
                      select new GlobalModel()
                    {
                      IndexModel = po

                       //SearchID = po.SearchID,
        //             //ReceivedDate = po.ReceivedDate,



                    }).ToList();

        }

这里,我正在传递要加载的视图的全局模型,该模型由两个子模型组成。现在,由于索引详细信息来自数据库,所以这里我也无法初始化所有参数,因为我试图将整个模型初始化到表中的字段,这是不可能的。

另外,我在po获取数据库表的所有字段。但是再次无法初始化,因为IndexModel引用了索引模型的整个参数。

所以,我被困在这里。我需要解决这个问题。我在哪里做错了??

2 个答案:

答案 0 :(得分:1)

我可以看到你只想循环索引模型,而SearchModel只有一个值。尝试这种方法:

将您的全局模型更改为:

public class GlobalModel
    {
        public SearchModel SearchModel { get; set; }
        public IEnumerable<IndexModel> IndexModels { get; set; }

    }

获取IndexModels的方法:

public IEnumerable<IndexModel> GetDetails()
        {
            return (from po in dbEntity.SearchDetails
                      select new IndexModel()
                    {
                      SearchNumber = po.SearchNumber,
                      SearchID = po.SearchID,
                      ReceivedDate = po.ReceivedDate 
                    }).ToList();

        }

在你的行动方法中:

public ActionResult Index()
        {
            var model = new GlobalModel():
            var model.IndexModels = GetDetails();
            return View(model); 
        }

最后在你的视图中:

@model ProjectName.Model.GlobalModel

@{
    ViewBag.Title = "Index";
}
<div style="padding-left: 40%">
        @using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))
        {
            @Html.AntiForgeryToken()
            @Html.ValidationSummary(true)

            <fieldset>
                <legend>Search</legend>
                  <ol>
                    <li>

                        <div class="editor-label">
                            @Html.LabelFor(model => model.SearchModel.FromDate)
                        </div>
                        <div class="editor-field">
                            @Html.EditorFor(model => model.SearchModel.FromDate)
                            @Html.ValidationMessageFor(model => model.SearchModel.FromDate)
                        </div>
                    </li>
                    <li>
                          <div class="editor-label">
                            @Html.LabelFor(model => model.SearchModel.ToDate)
                        </div>
                        <div class="editor-field">
                            @Html.EditorFor(model => model.SearchModel.ToDate)
                            @Html.ValidationMessageFor(model => model.SearchModel.ToDate)
                        </div>
                    </li>
                    <li>
                        @Html.DropDownListFor(model => model.SearchModel.SearchNumber, new SelectList(Model.ddlSearchNo.ddlSearchNumber, "Value", "Text"), "Select Search #", new { id="SearchID",onchange="GetSearchNo()" })
                        @Html.ValidationMessageFor(model => model.SearchModel.SearchNumber)
                    </li>
                </ol>
               </fieldset>

        }
    </div>

<div>
    <table style="border-collapse: separate; border-spacing: 15px;">
    <tr>
        <th style="text-align:center;">
            @Html.DisplayNameFor(model => model.IndexModels.SearchNumber)
        </th>
        <th style="text-align:center;">
            @Html.DisplayNameFor(model => model.IndexModels.SearchID)
        </th>
        <th style="text-align:center;">
            @Html.DisplayNameFor(model => model.IndexModels.ReceivedDate)
        </th>

       </tr>

@foreach (var item in Model.IndexModels) {
    <tr>
        <td style="text-align:center;">
            @Html.DisplayFor(modelItem => item.SearchNumber)
        </td>
       <td style="text-align:center;">
            @Html.DisplayFor(modelItem => item.SearchID)
        </td>

        <td style="text-align:center;">
            @Html.DisplayFor(modelItem => item.ReceivedDate)
        </td>

        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.SearchID}) |
            @Html.ActionLink("Details", "Details", new{id=item.SearchID}) |
            @Html.ActionLink("Delete", "Delete", new {id=item.SearchID })
        </td>
    </tr>
}

</table>

</div>

让我知道它是否有效。

答案 1 :(得分:0)

问题是因为您没有初始化Search模型和Index模型!

首先,您应该按如下方式修改GetDetails方法

  public IEnumerable<GlobalModel> GetDetails()
    {
        var models=(from po in dbEntity.SearchDetails.AsEnumerable()
                  select new GlobalModel()
                {
                  IndexModel = new IndexModel(){
                     /* FromDate= po. FromDate,
                      ToDate= po. ToDate,*/
                      },
                  SearchModel = new SearchModel(){
                       /*SearchID = po.SearchID,
                       ReceivedDate = po.ReceivedDate,*/
                     },
                }).ToList();

    }

此外,您最好为IndexModel类和SearchModel类创建一个空构造函数。此构造函数将初始化类字段/属性。