首页 > 解决方案 > 麻烦将数据从表单绑定到操作方法模型。列表在 ViewModel 中使用

问题描述

我正在学习 ASP.Net MVC Core,但在理解如何将表单数据绑定到我的操作方法的参数时遇到了一些麻烦。

我的 ViewModel 看起来像这样:

public class RemindUsersViewModel
    {
        public List<SelectListItem> UsersCompleted { get; set; } 
        public List<SelectListItem> UsersNotCompleted { get; set; }
        public Course Course { get; set; }
    }

我的表格如下所示:

@model List<RemindUsersViewModel>
...
@foreach (var e in Model)
{
..
<form asp-controller="ManageCourse" asp-action="RemindUsers" method="post">

    <ul>
        @for (int i = 0; i < e.UsersNotCompleted.Count; i++)
        {
            <li>
                <div>
                    <label>
                        <input type="checkbox" asp-for="@e.UsersNotCompleted[i].Selected" />
                        <span>@e.UsersNotCompleted[i].Text</span>
                    </label>
                </div>
                <input type="hidden" asp-for="@e.UsersNotCompleted[i].Text" />
            </li>
        }
        <li>
            <button type="submit">Send reminder</button>
        </li>
    </ul>

</form>


}

在 fiddler 中,我在选择 2/2 用户并提交后看到这些值发布在正文中:

e.UsersNotCompleted[2].Text =   robert@gud.se
e.UsersNotCompleted[2].Selected =   false
e.UsersNotCompleted[2].Selected =   true
e.UsersNotCompleted[1].Text =   robban@mail.se
e.UsersNotCompleted[1].Selected =   true
e.UsersNotCompleted[1].Selected =   false
e.UsersNotCompleted[0].Text =   test@test.se
e.UsersNotCompleted[0].Selected =   false
e.UsersNotCompleted[0].Selected =   true

我将如何继续在我的操作方法中正确绑定这些值?或者我应该重新设计我的 ViewModel?我不确定拥有我的 ViewModel 列表是否不正确。目前我正在用已完成或未完成特定课程的用户填写这些列表。

我想要实现的是允许管理员在列表中选择用户,然后让系统通过电子邮件提醒他们参加课程。是为了学校作业。提前致谢 :-)

标签: c#formsasp.net-core-mvcmodel-bindingselectlistitem

解决方案


标准做法是将单个 ViewModel 传递给视图。不是 ViewModel 的列表。

因此,如果我正确理解您的要求,我认为您的视图应如下所示:

@model RemindUsersViewModel
...

<form asp-controller="ManageCourse" asp-action="RemindUsers" method="post">

    <ul>
        @for (var i = 0; i < Model.UsersNotCompleted.Count; i++)
        {
            <li>
                <label>
                    <input asp-for="UsersNotCompleted[i].Selected" />
                    <span>@Model.UsersNotCompleted[i].Text</span>
                </label>
                <input type="hidden" asp-for="UsersNotCompleted[i].Text" />
            </li>
        }
        <li>
            <button type="submit">Send reminder</button>
        </li>
    </ul>

</form>

控制器动作签名将是:

public IActionResult RemindUsers(RemindUsersViewModel model)

根据您的回复更新:

您可以将 ViewModel 更改为:

public class RemindUsersViewModel
{
    public List<CourseModel> Courses { get; set; }        
}

public class CourseModel
{
    public List<SelectListItem> UsersCompleted { get; set; } 
    public List<SelectListItem> UsersNotCompleted { get; set; }
    public Course Course { get; set; }
}

然后使用双 for 循环保持视图的原始结构。外循环会循环Courses,内循环会循环UsersNotCompleted

请注意,您的页面上有多个表单。当您提交单个表单时,它应该 POST 到如下所示的操作签名:public IActionResult RemindUsers(RemindUsersViewModel model)


推荐阅读