IEnumerable<Model> 返回 null

IEnumerable<Model> returning null

我很难通过 IEnumerable 作为模型。数据正在填充一页上的表单 - 并且这样做是正确的。提交后模型 returns 为空。

我在这方面看到了各种 post,它们大多引用命名约定,因此我尝试了不同的参数命名方法,以避免模型绑定中的任何混淆。

我也尝试过各种模型和助手来尝试传递数据,结果都是一样的。

当前实施:

型号:

public class UserProfileListModel
{
    public IEnumerable<UserProfileViewModel> UserProfileViewModels { get; set; }
}

public class UserProfileViewModel
{
    public UserProfile UserProfile { get; set; }
    public Role UserRole { get; set; }
    public Team UserTeam { get; set; }
    public Scope UserScope { get; set; }
}

查看:

@model Project.WebUI.Models.UserPRofileListModel

SNIP

<fieldset>
    <legend>Administrate Users:</legend>
    <table class="adminTbl">
        <thead>
            <tr>
                <th>UserName:</th>
                <th>Role:</th>
                <th>Team:</th>
                <th>Scope:</th>
                <th>Update:</th>
                <th>Delete:</th>
            </tr>
        </thead>
        <tbody>
            @{foreach (var user in Model.UserProfileViewModels)
              {
                <tr>
                    <td>
                        <p>@user.UserProfile.UserName
                            @{if (!user.UserProfile.Membership.IsConfirmed)
                              {
                                  using (Html.BeginForm("Confirm", "Account", FormMethod.Post, null)){
                                @Html.AntiForgeryToken()
                                @Html.Hidden("Token", user.UserProfile.Membership.ConfirmationToken)
                                @Html.Hidden("Name", user.UserProfile.UserName)
                              }
                            <input type="submit" value="Confirm" />}
                            }
                        </p>
                    </td>

                    @{using (Html.BeginForm("SaveUserChanges", "Account", FormMethod.Post, null))
                      {         
                        @Html.AntiForgeryToken()
                        @Html.HiddenFor(u => user.UserProfile)
                          if (user.UserProfile.UserName != User.Identity.Name && user.UserProfile.Membership.IsConfirmed)
                          {
                            <td>
                                @Html.DropDownListFor(u => user.UserRole, Project.WebUI.Controllers.AccountController.RoleList, new { @class = "formdrop" })
                            </td>
                            <td>
                                @Html.DropDownListFor(u => user.UserTeam, Project.WebUI.Controllers.AccountController.TeamList, new { @class = "formdrop" })
                            </td>
                            <td>
                                @Html.DropDownListFor(u => user.UserScope, Project.WebUI.Controllers.AccountController.ScopeList, new { @class = "formdrop" })
                            </td>
                            <td>
                                <input type="submit" value="Save Changes" onclick="return confirm('Are you sure you wish to update this user? ')" />
                            </td>
                            }
                            else
                            {
                              /*If user is self or not yet confirmed these are here to buffer the delete button into the last cell*/
                                <td></td>
                                <td></td>
                                <td></td>
                                <td></td>
                            }
                          }
                        }
                        <td>
                        @Html.ActionLink("Delete", "Delete", new { user.UserProfile.UserId }, new
                       {
                           onclick = "return confirm('Warning: Action cannot be undone. Are you sure you wish to permanently delete this entry?')"
                       })
                        </td>
                </tr>
              }
            }
        </tbody>
    </table>
</fieldset>

控制器:

填充视图:

    public ActionResult AdministrateUsers()
    {
        populateLists();

        var query = repository.UserProfiles.OrderBy(e => e.UserName);
        List<UserProfileViewModel> list = new List<UserProfileViewModel>();

        foreach(UserProfile up in query)
        {
            UserProfileViewModel vm = new UserProfileViewModel() { UserProfile = up };
            list.Add(vm);
        }

        UserProfileListModel models = new UserProfileListModel() 
        { 
           UserProfileViewModels = list.OrderBy(up => up.UserProfile.UserName)
        };

        return View(models);
    }

接受帖子:

    public ActionResult SaveUserChanges(UserProfileListModel model)
    {
        foreach (UserProfileViewModel upvm in model.UserProfileViewModels)
        {

            UserProfile up = new UserProfile()
            {
                UserId = upvm.UserProfile.UserId,
                UserEmail = upvm.UserProfile.UserName,
                UserName = upvm.UserProfile.UserName
            };

            if (ModelState.IsValid)
            {
                repository.SaveUserProfile(up);
            }
            else
            {
                return View(model);
            }
        }
        return RedirectToAction("Index", "Admin");
    }

代码仍然需要大量工作,但我无法在 post 上将模型返回控制器。我还尝试返回 UserProfileViewModel 而不是整个列表。

谁能告诉我哪里做错了?

谢谢!

您可能需要在 POST 方法中绑定属性,如下所示:

  public ActionResult Create([Bind(Include = "Id,Subject,Text,IsImportant")] Announcment announcment) {... }

所以它将是:

public ActionResult SaveUserChanges([Bind(Include = "UserProfile,Role,UserTeam,UserScope")]UserProfileListModel model)

您是否已指定您的操作方法用于 HTTP Post?并更改您的操作方法以接受 UserProfileViewModels。

[HttpPost]
public ActionResult SaveUserChanges(UserProfileViewModels model)
{

您也只 post返回一个模型:UserProfileViewModels。 您的 foreach 循环中有您的表单,因此每个 UserProfileViewModels 都有自己的表单。如果您想将其更改为 post 返回您的 UserProfileListModel,请移动

@{using (Html.BeginForm("SaveUserChanges", "Account", FormMethod.Post, null))

在你的 foreach 之外。

您有很多无效的 html,包括作为 tr 元素的子元素的 form 元素和重复的 id 属性。如果你想 post 返回 UserProfileListModel 那么你需要一个 form 元素并使用 EditorTemplatefor 循环(而不是 foreach)呈现控件,以便使用索引器正确命名它们。

您还试图将下拉列表绑定到复杂对象(例如 UserProfileRole 等)。 <select> 元素(和所有表单控件)仅 post 返回 key/value 对,因此您需要绑定到值类型(例如 UserProfile.UserId)。

您的 SaveUserChanges() post 方法也在尝试访问 UserProfile 的属性,但您甚至没有以 post 返回到此方法(例如 UserId = upvm.UserProfile.UserId, UserEmail = upvm.UserProfile.UserName, ...),因此它们将始终为空。