Identity UpdateAsync会丢失IdentityResult.Failed

时间:2014-03-04 14:03:13

标签: c# asp.net asp.net-mvc asp.net-identity

我为ASP.NET身份编写了一个自定义UserStore,我在ASP.NET MVC 5.1应用程序中使用它。一切都按预期工作,我对ASP.NET的这个新功能(身份)非常满意......

问题是我认为差不多2天,因为我试图从UpdateAsync方法返回一个错误,不知怎的,似乎我无法返回任何内容。

LE:我正在使用ASP.NET Identity Core 2.0.0-beta1

这是我的代码,几行:

public Task UpdateAsync(IdentityUser user)
{
    AdminUserEntity userEntity = new AdminUserEntity();
    userEntity.IsNew = false;
    userEntity.Id = user.UserModel.Id;
    userEntity.UserCompleteName = user.UserModel.UserCompleteName;
    userEntity.IsDisabled = user.UserModel.IsDisabled;

    if (!String.IsNullOrEmpty(user.UserModel.PasswordHash))
        userEntity.PasswordHash = user.UserModel.PasswordHash;

    if (user.Claims != null && user.Claims.Count > 0)
    {
        foreach (Claim claim in user.Claims)
        {
            AdminUserClaimEntity claimEntity = userEntity.AdminUserClaims.AddNew();
            claimEntity.AdminUserUniqueId = user.UserModel.UniqueId;
            claimEntity.ClaimType = claim.Type;
            claimEntity.ClaimValue = claim.Value;
        }
    }

    try
    {
        byte[] timestamp = Convert.FromBase64String(user.UserModel.Timestamp);
        AdminUserEntityManagement.UpdateCompleteAdminUserEntity(userEntity, timestamp);
    }
    catch (Exception exception)
    {
        List<string> errors = new List<string>() {exception.Message};
        return Task.FromResult<IdentityResult>(IdentityResult.Failed(errors.ToArray()));
    }

    return Task.FromResult<object>(null);
}

虽然存在异常且catch块正在执行,但以下行始终返回成功:

IdentityResult result = await UserManager.UpdateAsync(identityUser);

有人可以告诉我我错过了什么吗?

2 个答案:

答案 0 :(得分:2)

我假设这个UpdateAsync在你的ApplicationUserManager类中,签名不应该是

public override Task<IdentityResult> UpdateAsync 

如果您尝试更改UserManager的UpdateAsync方法的工作方式。

答案 1 :(得分:2)

首先,@ hao-kung,谢谢你的帮助。现在我可以说我已经看到了大局。虽然我不能说我喜欢它,但我理解UserManager是如何工作的。

另外,如果你认为我说错了,请纠正我。

对于其他人来说,为了自定义UserManager的行为(即使你只想表现出一个你无论如何都能在UserStore自定义类中捕获的错误),你必须遵循这些步骤(为了更好地理解,我将举例说明描述我为了捕获UpdateAsync方法的业务异常并在界面中显示它所做的事情:

  1. 在UserStore类(应该在IUserStore接口的其他接口中实现)中,不要捕获任何异常。

    public Task UpdateAsync(IdentityUser user)
    {
        // here an exception will be thrown if there is a concurrency issue
        byte[] timestamp = Convert.FromBase64String(user.UserModel.Timestamp);
        AdminUserEntityManagement.UpdateCompleteAdminUserEntity(userEntity, timestamp);
        return Task.FromResult<object>(null);
    }
    
  2. 扩展UserManager类并覆盖您要自定义的方法(捕获先前抛出的业务异常并将其显示到接口):

    public class AdminUserManager : UserManager<IdentityUser>
    
    
    public override async Task<IdentityResult> UpdateAsync(IdentityUser user)
    {
        Task<IdentityResult> result = base.UpdateAsync(user);
    
        try
        {
            IdentityResult identityResult = await result;
        }
        catch (Exception exception)
        {
            List<string> errors = new List<string>() { exception.Message };
            return IdentityResult.Failed(errors.ToArray());
        }
    
        return result.Result;
    }
    
  3. 在MVC控制器中(例如)从扩展的UserManager类中读取UpdateAsync方法的结果:

    IdentityResult result = await UserManager.UpdateAsync(identityUser);
    if (result.Succeeded)
    {
      this.SetNotification("The user has been updated.", EnumToastrNotificationType.Info);
      return RedirectToAction("ShowUsers", "UserManagement");
    }
    else
    {
      this.AddErrors(result);
    }