繁体   English   中英

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

[英]ASP.NET EF6 Identity 2 Update User Claims Error Updating For User

我有一个Web应用程序,其中使用ASP.NET Identity 2 Claims作为该站点用户的访问控制列表。 我在ApplicationUser模型中正确使用了所有索赔,该模型有一个Claims列表。

我正在尝试为用户清除索赔,然后为他们提供整套新索赔。 我有一个索赔组对象,其中包含索赔项列表

[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包含对User的引用)。
  2. 我有一个try catch块,因为它引发了一些验证错误。 跟踪显示的错误消息是:

类:System.Data.Entity.DynamicProxies.IdentityUserClaim_FCA22938ED9E4AAF12F5F2E4717CA49CC6F53B512CF2A371AA0C95D210D35870,属性:UserId,错误:UserId字段为必填字段。

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

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

await UserManager.UpdateAsync(appUser);

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

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

我知道了 由于某种原因,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 });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM