ASP.NET EF6身份2更新用户声明错误更新用户

时间:2014-11-25 06:49:00

标签: c# asp.net-mvc asp.net-mvc-5 claims-based-identity asp.net-identity-2

我有一个Web应用程序,我在其中使用ASP.NET Identity 2 Claims来获取该站点用户的访问控制列表。我在ApplicationUser模型中正确地提供了所有声明,其中包含声明列表。

我试图清除用户的声明,然后给他们一整套新的声明。 我有一个Claim Group对象,其中包含一个Claim Items列表

[HttpPost, ValidateAntiForgeryToken]
    public async Task<ActionResult> Claims_UpdateByClaimGroup([Bind(Include = "Id,SelectedClaimGroupId")] UserClaimsViewModel viewModel)
    {
        User user = await _repository.GetAsync<User>(viewModel.Id);
        ApplicationUser appUser = await UserManager.FindByIdAsync(user.AppUser.Id);
        var claimGroup = await _repository.GetAsync<ClaimGroup>(Convert.ToInt32(viewModel.SelectedClaimGroupId));

        appUser.Claims.Clear();// Clear all the claims first

        // Then add the new claims.
        foreach (ClaimGroupItems claimGroupItem in claimGroup.Items)
        {
            //UserManager.AddClaim(user.AppUser.Id, new Claim(claimGroupItem.MenuItemId.ToString(), claimGroupItem.ClaimValue));
            appUser.Claims.Add(new IdentityUserClaim()
            {
                ClaimType = claimGroupItem.MenuItemId.ToString(),
                ClaimValue = claimGroupItem.ClaimValue,
                UserId = user.AppUser.Id,
            });
        }

        try
        {
            _repository.Save<User>(appUser.User);
            //await UserManager.UpdateAsync(appUser);
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
                        validationErrors.Entry.Entity.GetType().FullName,
                        validationError.PropertyName,
                        validationError.ErrorMessage);
                }
            }

            throw;  // You can also choose to handle the exception here...
        }

        return RedirectToAction("Claims", new { id = viewModel.Id, Updated = true });
    }

你可以在这里看到一些东西:

  1. 我试图在不使用UserManager方法的情况下删除,添加和保存ApplicationUser.Claims对象上的声明。 (ApplicationUser包含对用户的引用)。
  2. 我有一个try catch块,因为它会抛出一些验证错误。 跟踪中出现的错误消息是:
  3.   

    类别:   System.Data.Entity.DynamicProxies.IdentityUserClaim_FCA22938ED9E4AAF12F5F2E4717CA49CC6F53B512CF2A371AA0C95D210D35870,   属性:UserId,错误:UserId字段是必需的。

    1. 如果我尝试使用UserManager方法,我会收到同样的错误。

      UserManager.AddClaim(user.AppUser.Id,new Claim(claimGroupItem.MenuItemId.ToString(),claimGroupItem.ClaimValue));

    2. await UserManager.UpdateAsync(appUser);
      

      该错误是由以下原因引起的: appUser.Claims.Clear();

      如何正确更新用户的声明?

1 个答案:

答案 0 :(得分:0)

我得到了它的工作。由于某种原因,appUser.Claims.Clear()无法正常工作,导致userId为null错误。所以我在一个循环中手动删除了旧的声明,现在一切正常。

[HttpPost, ValidateAntiForgeryToken]
public async Task<ActionResult> Claims_UpdateByClaimGroup([Bind(Include = "Id,SelectedClaimGroupId")] UserClaimsViewModel viewModel)
{
    var claimGroup = await _repository.GetAsync<ClaimGroup>(Convert.ToInt32(viewModel.SelectedClaimGroupId));
    User user = await _repository.GetAsync<User>(viewModel.Id);
    ApplicationUser appUser = await UserManager.FindByIdAsync(user.AppUser.Id);

    // Remove all the old claims
    var listToRemove = appUser.Claims.ToArray();
    foreach (var item in listToRemove)
    {
        await UserManager.RemoveClaimAsync(item.UserId, new Claim(item.ClaimType, item.ClaimValue));
    }

    try
    {
        // Then add the new claims.
        foreach (ClaimGroupItems claimGroupItem in claimGroup.Items)
        {
            //UserManager.AddClaim(appUser.Id, new Claim(claimGroupItem.MenuItemId.ToString(), claimGroupItem.ClaimValue));
            appUser.Claims.Add(new IdentityUserClaim()
            {
                UserId = appUser.Id,
                ClaimType = claimGroupItem.MenuItemId.ToString(),
                ClaimValue = claimGroupItem.ClaimValue,
            });
        }
        await UserManager.UpdateAsync(appUser);
    }
    catch (DbEntityValidationException dbEx)
    {
        foreach (var validationErrors in dbEx.EntityValidationErrors)
        {
            foreach (var validationError in validationErrors.ValidationErrors)
            {
                Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}",
                    validationErrors.Entry.Entity.GetType().FullName,
                    validationError.PropertyName,
                    validationError.ErrorMessage);
            }
        }

        throw;  // You can also choose to handle the exception here...
    }

    return RedirectToAction("Claims", new { id = viewModel.Id, Updated = true });
}