IEnumerable <model>返回null </model>

时间:2015-01-07 22:52:48

标签: c# asp.net-mvc entity-framework

我很难将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

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

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

谁能说出我做错了什么?

谢谢!

3 个答案:

答案 0 :(得分:0)

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

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

所以它会是:

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

答案 1 :(得分:0)

您是否指定了您的操作方法适用于HTTP Post?并将您的操作方法更改为接受UserProfileViewModels。

[HttpPost]
public ActionResult SaveUserChanges(UserProfileViewModels model)
{

您还只回发了一个模型:UserProfileViewModels。 你的表单在foreach循环中,因此每个UserProfileViewModels都有自己的表单。如果要更改它以回发UserProfileListModel,请移动

@{using (Html.BeginForm("SaveUserChanges", "Account", FormMethod.Post, null))
在你的foreach之外。

答案 2 :(得分:0)

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

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

您的SaveUserChanges()帖子方法也在尝试UserProfile的访问属性,但您甚至无法在回复此方法的表单中控制UserProfile的属性(例如UserId = upvm.UserProfile.UserId, UserEmail = upvm.UserProfile.UserName, ...)所以它们总是为空。