Viewmodel IEnumerable属性为空

时间:2013-05-10 20:42:12

标签: object asp.net-mvc-4 view controller ienumerable

我正在制作基于ASP .NET MVC4的应用程序。我是该领域的完整新手。这个想法非常简单 - 在数据库中有一些成员,显示它们列出,通过复选框选择所需的成员并重定向到其他控制器,这些控制器可以对之前选择的成员执行某些操作。

问题是将成员列表从View传递给Controller。我认为它可以与ViewModel一起使用。它当然可以从Controller到View,但不是其他方式。

我的ViewModel:

public class MembersViewModel
{
    public IEnumerable<Directory_MVC.Models.Member> MembersEnum { get; set; }

    public string Test { get; set; }
}

我的控制器片段:

public class MembersController : Controller
{
    private MainDBContext db = new MainDBContext();

    public ActionResult Index()
    {
        var model = new Directory_MVC.ViewModels.MembersViewModel();

        // populating from DB
        model.MembersEnum = db.Members.Include(m => m.Group).Include(m => m.Mother).Include(m => m.Father);

        model.Test = "abc";

        return View(model);
    }

    [HttpPost]
    public ActionResult GoToSendEmail(Directory_MVC.ViewModels.MembersViewModel returnedStruct)
    {
        if (ModelState.IsValid)
        {
            // it is valid here
            return Redirect("http:\\google.com");
        }
    }

我的观点片段:

@model Directory_MVC.ViewModels.MembersViewModel


@{
ViewBag.Title = "Members listing";

var lineCount = 0;
string lineStyle;
}

@using (Html.BeginForm("GoToSendEmail", "Members", FormMethod.Post))
{
<table>
@foreach (var item in Model.MembersEnum)
{
    lineCount++;

    // set styling
    if (lineCount % 2 == 1)
    {
        lineStyle = "odd-line";
    }
    else
    {
        lineStyle = "even-line";
    }

    <tr class="@lineStyle">
        <td>
            @Html.EditorFor(modelItem => item.Selected)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.FirstName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Mother.FirstName) @Html.DisplayFor(modelItem => item.Mother.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Father.FirstName) @Html.DisplayFor(modelItem => item.Father.LastName)
        </td>
  <!-- other print-outs but not all properties of Member or Mother/father are printed -->
    </tr>
 }

</table>

<input type="submit" value="Send E-mail" />
}

数据在视图中显示为OK。但是,当我提交该表单时,在Controller的方法GoToSendEmail中,returnedStruct.MembersEnum和Test字符串都为null

是否存在错误,或者是否有其他可能的方法来传递该成员结构并检查其Selected属性?

2 个答案:

答案 0 :(得分:1)

模型绑定到集合的工作方式略有不同。每个项目都必须有一个标识符,以便所有输入都不具有相同的名称。我回答了similar question here

@for (int i = 0; i < Model.MembersEnum.Count(); i++)
{
    @Html.EditorFor(modelItem => modelItem.MembersEnum[i].FirstName)
}

......应该呈现类似......

<input type="text" name="MembersEnum[0].FirstName" value="" />
<input type="text" name="MembersEnum[1].FirstName" value="" />
<input type="text" name="MembersEnum[2].FirstName" value="" />

...当控制器拿起时,应该在ViewModel中填充集合......

public ActionResult GoToSendEmail(ViewModels.MembersViewModel model)

正如其他答案所述,我会看一下Scott HanslemanPhil Haack的相关文章。

您还提到,当您提交Test操作时,名为null的字符串为POST。您尚未在表单中的任何位置为此属性添加字段,因此模型绑定器无法绑定到该字段。如果您在表单中为其添加字段,则应在POST操作中看到该值:

@Html.EditorFor(modelItem => modelItem.Test)

答案 1 :(得分:0)

Html.BeginCollectionItem()帮助器完成了这项工作 - BeginCollectionItem