为什么viewmodel的一部分是Null?

Why is part of viewmodel Null?

我有一个视图模型,我用它来授予和删除管理员权限。

包括以下内容

    namespace PenedaVes.ViewModels
{
    public class RootViewModel
    {
        public List<UserBox> UserBoxesList;
        public string TestAtributte { get; set; }
    }

    public class UserBox
    {
        public string UserId { get; set; }
        public string Username { get; set; }
        public bool IsChecked { get; set; }
    }
}

Test 属性仅用于调试,以检查整个视图模型是否为 null 或只是列表。 然后我有一个控制器,称为 Panel 控制器,它有一个 get 和一个 post 方法:

        public async Task<IActionResult> Index()
        {
            List<ApplicationUser> users = await _userManager.Users.ToListAsync();

            List<UserBox> userBoxes = new List<UserBox>();
            
            foreach(ApplicationUser user in users)
            {
                if (await _userManager.IsInRoleAsync(user, "Root")) continue;
                UserBox ub = new UserBox
                {
                    UserId = user.Id,
                    Username = user.UserName,
                    IsChecked = await _userManager.IsInRoleAsync(user, "Admin")
                };
                    
                userBoxes.Add(ub);
            }

            RootViewModel vm = new RootViewModel {UserBoxesList = userBoxes, tipo = "Hello"};
            
            return View(vm);
        }

        [HttpPost]
        public async Task<IActionResult> ChangePermissions(RootViewModel vm)
        {

           Console.WriteLine(vm.Test)
           Console.WriteLine(vm.UserBoxerList.Count)
        }

最终使用的视图如下:

@model RootViewModel

@{
    ViewData["Title"] = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>Admin permissions pannel</h1>

<form asp-controller="Panel" asp-action="ChangePermissions" method="post">
    <table>
        <h3> User List</h3>
        @for (int i = 0; i < Model.UserBoxesList.Count; i++)
        {
            @if (i % 3 == 0)
            {
                @:<tr></tr>
            }
            <td>
                @Html.CheckBoxFor(model => model.UserBoxesList[i].IsChecked)
                <label> @Model.UserBoxesList[i].Username</label>
                @Html.HiddenFor(model => model.UserBoxesList[i].Username)
                @Html.HiddenFor(model => model.UserBoxesList[i].UserId)
            </td>
        }
    </table>
    
    <div class="form-group form-check">
        <label class="control-label">
            <input class="form-check-input" asp-for="@Model.TestAtributte" /> This is a test attribute
        </label>
    </div>
    
    <input type="submit" value="Change" class="btn btn-primary" />
</form>

每当我提交此表单时,TestAtribute 总是带有新值,但是,列表作为空值出现并抛出 NullReferenceException,这让我感到困惑,因为它在视图中显示时不是空的。

如有任何帮助,我们将不胜感激。

Whenever I submit this form the TestAtribute always comes with the new value, however, the list comes as a null value and throws a NullReferenceException

那是因为您的模型中的 UserBoxesList 是一个字段而不是 属性。

修改您的模型如下:

public class RootViewModel
{
    public List<UserBox> UserBoxesList { get; set; }
    public string TestAtributte { get; set; }
}

当您通过 ChangePermissions 方法发帖时,RootViewModel 视图 你已经作为参数传递将使 UserBoxesList 为空,因为你的模型 class RootViewModel 没有初始化 UserBoxesList。

试试这个:

public class RootViewModel
{
    public List<UserBox> UserBoxesList;
    public string TestAtributte { get; set; }

    public RootViewModel()
    {
       UserBoxesList = new List<UserBox>();
    }
}

这在过去对模型中的集合和复杂 class 结构有用。