IEnumerable<Model> returning null

本文关键字:returning null gt Model IEnumerable lt | 更新日期: 2023-09-27 18:36:35

我很难通过IEnumerable作为模型。数据在一个页面上填充表单 - 并且正确填写。提交后,模型返回为 null。

我已经看到了关于此的各种帖子,它们主要引用命名约定,因此我尝试了不同的参数命名方法,以避免模型绑定中的任何混淆。

我还尝试了各种模型和帮助程序来尝试传递数据,并且都有相同的结果。

当前实现:

模型:

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

剪 断

<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");
    }

代码仍然需要大量工作,但我无法摆脱在发布时将模型返回控制器。我也尝试返回UserProfileViewModel而不是整个列表。

谁能说出我做错了什么?

谢谢!

IEnumerable<Model> returning null

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

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

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

你需要在

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)
{

您也只回发一个模型:UserProfileViewModels。您的表单位于 foreach 循环中,因此每个 UserProfileViewModels 都有自己的窗体。如果要更改它以回发您的用户配置文件列表模型,请移动

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

在你的前方之外。