【问题标题】:Update user information 2 cases - with password and without password更新用户信息2种情况——有密码和无密码
【发布时间】:2021-12-06 13:32:59
【问题描述】:

我有一个管理面板,并希望有两个选项来作为管理员更新用户信息。一种情况是我只想更新用户角色,另一种情况是我想更新所有信息,包括用户忘记密码时的密码。

RegisterModel.cs:

  public class RegisterModel
  {
    public string Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string UserRoles { get; set; }
    public byte[] ProfilePicture { get; set; }

    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    //[Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    //[Required]
    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
  }

AuthorizeController.cs

public async Task<IActionResult> UpdateUser([FromBody] RegisterModel model)
{
  ApplicationUser existingUser = await this.UserManager.FindByIdAsync(model.Id);

  if (!string.IsNullOrEmpty(model.Email))
  {
    IList<string> existingRoles = await this.UserManager.GetRolesAsync(existingUser);

    IdentityResult output = await this.UserManager.RemoveFromRoleAsync(existingUser, existingRoles.FirstOrDefault());
    IdentityResult resultat = await this.UserManager.AddToRoleAsync(existingUser, model.UserRoles);

    Collection<ApplicationUserRole> userRoles = new();
    userRoles.Add(new ApplicationUserRole { Name = model.UserRoles });

    existingUser.Email = model.Email;
    existingUser.FirstName = model.FirstName;
    existingUser.LastName = model.LastName;
    existingUser.ProfilePicture = model.ProfilePicture;
    existingUser.UserRoles = userRoles;

    if (!string.IsNullOrEmpty(model.Password))
    {
      existingUser.PasswordHash = this.PasswordHasher.HashPassword(existingUser, model.Password);
      existingUser.PasswordHash = this.PasswordHasher.HashPassword(existingUser, model.ConfirmPassword);
    }

    IdentityResult result = await this.UserManager.UpdateAsync(existingUser);

    if (!result.Succeeded)
    {
      var errors = result.Errors.Select(x => x.Description);

      return BadRequest(new RegisterResult { Successful = false, Errors = errors });
    }

    return Ok(new RegisterResult { Successful = true });
  }

  return NotFound("User not found!");
}

目前我无法将 RegisterModel.cs 密码字段设置为必填,因为在这种情况下我不能将它们留空。但是,我使用相同的模型来创建新用户,在这种情况下,它们是必需的。 当前代码也在数据库中进行了必要的更改,但我遇到了一个异常:

IdentityResult result = await this.UserManager.UpdateAsync(existingUser);

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未处理的异常呈现组件:“S”是一个无效的值开始。路径:$ |行号:0 |字节位置内线:0。 System.Text.Json.JsonException:“S”是值的无效开始。 路径:$ |行号:0 | BytePositionInLine: 0. ---> System.Text.Json.JsonReaderException:'S' 是一个无效的开始 价值。行号:0 | BytePositionInLine:0。在 System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource 资源, 字节 nextByte, ReadOnlySpan1 bytes) at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker) at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first) at System.Text.Json.Utf8JsonReader.ReadSingleSegment() at System.Text.Json.Utf8JsonReader.Read() at System.Text.Json.Serialization.JsonConverter1[[Blazing.Shared.RegisterResult, Blazing.Shared,版本=1.0.0.0,文化=中性, PublicKeyToken=null]].ReadCore(Utf8JsonReader& 阅读器, JsonSerializerOptions options, ReadStack& state) --- 内部结束 异常堆栈跟踪 --- 在 System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& 状态, JsonReaderException ex) 在 System.Text.Json.Serialization.JsonConverter1[[Blazing.Shared.RegisterResult, Blazing.Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].ReadCore(Utf8JsonReader&amp; reader, JsonSerializerOptions options, ReadStack&amp; state) at System.Text.Json.JsonSerializer.ReadCore[RegisterResult](JsonConverter jsonConverter, Utf8JsonReader&amp; reader, JsonSerializerOptions options, ReadStack&amp; state) at System.Text.Json.JsonSerializer.ReadCore[RegisterResult](JsonReaderState&amp; readerState, Boolean isFinalBlock, ReadOnlySpan1 缓冲区, JsonSerializerOptions 选项、ReadStack& 状态、JsonConverter 转换器基础)在 System.Text.Json.JsonSerializer.ContinueDeserialize[RegisterResult](ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack, JsonConverter 转换器,JsonSerializerOptions 选项)在 System.Text.Json.JsonSerializer.d__651[[Blazing.Shared.RegisterResult, Blazing.Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext() at System.Net.Http.Json.HttpContentJsonExtensions.&lt;ReadFromJsonAsyncCore&gt;d__41[[Blazing.Shared.RegisterResult, Blazing.Shared,版本=1.0.0.0,文化=中性, PublicKeyToken=null]].MoveNext()

【问题讨论】:

  • 你好,如果我没有误解你的场景,如果你坚持使用一个用户模型来创建和更新页面,我认为你需要编写一些业务逻辑。您可以调试UpdateAsync 方法来找出问题或提供更多代码详细信息来解决您的错误。

标签: c# asp.net-core blazor


【解决方案1】:

根据您的描述,您有一个new user creation page 和一个admin update user page,它们使用相同的用户模型,创建新用户时需要密码,而更新用户时不需要密码。所以你面前有两种方式。

为更新页面创建一个新的用户模型。你知道这很容易,但我认为当你选择在这里提问时,你的目标不是这个。所以我认为你必须在这里添加更多的业务逻辑。

例如你可以将密码属性改为不需要,并要求你的创建/更新按钮的点击事件来检查这个动作是否需要输入密码,并且在你的后端代码中,你也可以添加判断代码如果这个传入请求是“需要密码”请求,当不符合规则时返回错误以避免有人直接调用后端控制器。这种方式将检查所需的密码留给您自己的代码。

另一种方法是仍然需要密码,但现在您需要为“不需要密码”场景编写代码。当您的后端收到“不需要密码”的请求时,它应该先从数据库中查询密码,并在模型验证之前将密码添加到数据模型中,这样它也可以使密码成为“必填”。

[HttpPost]
        public IActionResult Edit([Bind("name,age,password")] UserModel user)
        {
            //password is required here 
            //if without the line-code below and the password is null here, it will return "password is required"
            user.password = "cccc";
            //Data validation
            if (ModelState.IsValid)
            {
                
                return RedirectToAction(nameof(Index));
            }
            return View(user);
        }

根据你的错误信息,我找到了a blog shared similar issue,所以我认为你需要检查UserManager.UpdateAsync返回了哪些数据以及是否是IdentityResult

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 2018-01-25
    • 2011-07-04
    相关资源
    最近更新 更多