更新用户信息时,viewmodel 为 null

When updating user information viewmodel is null

提问人:Bart Brouwers 提问时间:3/21/2021 最后编辑:Bart Brouwers 更新时间:3/22/2021 访问量:163

问:

错误:NullReferenceException:对象引用未设置为对象的实例。 ManageController.cs 中的 Web.Controllers.ManageController.ChangeUser(BaseViewModel model) + 用户。名字 = 模型。ChangeUserViewModel.名字;

我不明白为什么我会收到这个错误,你能帮我找到我做错了什么吗?

我试图实现的是通过我的视图模型更新用户信息。

您能告诉我尝试的方式是否正确吗?

BaseViewModel:

public class BaseViewModel
{
    public IndexViewModel IndexViewModel { get; set; }
    public ChangeUserViewModel ChangeUserViewModel { get; set; }
}

ChangeUserViewModel:

public class ChangeUserViewModel
{
    [Required]
    [StringLength(20, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 1)]
    public string FirstName { get; set; }
    [Required]
    [StringLength(20, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 1)]
    public string LastName { get; set; }
    
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }
    
    [Display(Name = "Profile Picture")]
    [DataType(DataType.Upload)]
    [MaxFileSize(5* 1024 * 1024)]
    [AllowedExtensions(new string[] { ".jpg", ".png", ".jpeg", ".gif", ".tif" })]

    public IFormFile ProfilePicture { get; set; }
}

控制器:

   public async Task<IActionResult> Index()
    {
        var user = await GetCurrentUserAsync();
        var model = new BaseViewModel
        {
            IndexViewModel = new IndexViewModel
            {
                HasPassword = await _userManager.HasPasswordAsync(user),
                PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
                TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
                Logins = await _userManager.GetLoginsAsync(user),
                BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user),
                AuthenticatorKey = await _userManager.GetAuthenticatorKeyAsync(user),
            },
            ChangeUserViewModel = new ChangeUserViewModel
            {
                FirstName = user.FirstName,
                LastName = user.LastName,
                Email = user.Email
            }
        };

        return View(model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> ChangeUser(BaseViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return RedirectToAction("Index", "Manage");
        }
        
        var user = await GetCurrentUserAsync();
        if (user != null)
        {
            user.FirstName = model.ChangeUserViewModel.FirstName;
            user.LastName = model.ChangeUserViewModel.LastName;
            user.Email = model.ChangeUserViewModel.Email;

            await _userManager.UpdateAsync(user);
        }

        return View("Index", model);
    }

视图:

@model BaseViewModel
@inject UserManager<ApplicationUser> UserManager
@{
    ViewData["Title"] = "Manage your account";
}

    <h2 class="content-heading pt-0">
        <i class="fa fa-fw fa-user-circle text-muted mr-1"></i> User Profile
    </h2>
    
    <form asp-controller="Manage" asp-action="ChangeUser" method="post" class="form-horizontal" role="form" enctype="multipart/form-data">
        <div class="row push">
            <div class="col-lg-4">
                <p class="text-muted">
                    Your account’s vital info.
                </p>
            </div>
            
            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="col-lg-8 col-xl-5">
                <div class="form-group">
                    <label for="dm-profile-edit-firstname">Firstname</label>
                    <input asp-for="ChangeViewModel.FirstName" type="text" class="form-control" id="dm-profile-edit-firstname" name="dm-profile-edit-firstname" >
                </div>
                <div class="form-group">
                    <label for="dm-profile-edit-lastname">Lastname</label>
                    <input asp-for="ChangeViewModel.LastName" type="text" class="form-control" id="dm-profile-edit-lastname" name="dm-profile-edit-lastname">
                </div>
                <div class="form-group">
                    <label for="dm-profile-edit-email">Email Address</label>
                    <input asp-for="ChangeViewModel.Email" type="email" class="form-control" id="dm-profile-edit-email" name="dm-profile-edit-email">
                </div>
                <div class="form-group">
                    <label>Your Avatar</label>
                    <div class="push">
                        <img class="img-avatar" src="@Url.Action("ProfilePicture", "Account" )" alt="">
                    </div>
                    <div class="custom-file">
                        <input asp-for="ChangeViewModel.ProfilePicture" type="file" class="custom-file-input js-custom-file-input-enabled" data-toggle="custom-file-input" id="ProfilePicture" name="ProfilePicture">
                        <label class="custom-file-label" for="ProfilePicture">Choose a new avatar</label>
                    </div>
                </div>
                                    
                <div class="form-group">
                    <button type="submit" class="btn btn-alt-primary">
                        <i class="fa fa-check-circle mr-1"></i> Update Profile
                    </button>
                </div>
            </div>
        </div>
    </form>
asp.net-mvc asp.net-core 视图模型 nullreferenceexception

评论

0赞 Serge 3/21/2021
我可以在您的代码中看到 BaseViewModel 和 BaseManageViewModel、ChangeUserViewModel 和 ChangeVitalUserInfoViewModel。你的真实代码是什么?在你发布你的真实代码之前,没有人能帮忙。您发布的代码将不会被编译。
0赞 Bart Brouwers 3/21/2021
嗨,@Sergey thnx提到它。我更新了代码
0赞 Bart Brouwers 3/21/2021
嗨,谢尔盖,我不明白你的答案。我有一个 ManageController,在控制器中我有多个 ActionResults(ChangeUser、ChangePassword、AddPhoneNumber)。对于所有这些 ActionResults,我都有一个 ViewModel。ChangeUserViewModel、ChangePasswordViewModel...。现在我需要有一个视图。在该视图中,我使用 BaseViewModel。在该视图中,我需要为每个 ActionResult 提供多个表单。问题是,当我在 ChangeUser 表单中点击提交时,我得到一个空引用异常。

答:

0赞 Michael Wang 3/22/2021 #1

控制器似乎没有收到来自视图的 when do post 请求。我建议你可以用代替.BaseViewModelNewtonsoft’s Json.NETSystem.Text.Json

第1步。安装以下 Nuget 包

Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson

第2步。 如果你从现有项目迁移,你将调用“AddMvc()”,然后你可以像这样将其附加到它上面:

services.AddMvc().AddNewtonsoftJson();

但是,在新的 3+ 项目中,您有一组不同的调用来替换 MVC。因此,您可能会遇到以下情况之一:.NET Core

services.AddControllers().AddNewtonsoftJson();
services.AddControllersWithViews().AddNewtonsoftJson();
services.AddRazorPages().AddNewtonsoftJson();

然后,将断点放在控制器代码中以检查 的值。BaseViewModel model