我有一个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 });
}
你可以在这里看到一些东西:
类别: System.Data.Entity.DynamicProxies.IdentityUserClaim_FCA22938ED9E4AAF12F5F2E4717CA49CC6F53B512CF2A371AA0C95D210D35870, 属性:UserId,错误:UserId字段是必需的。
如果我尝试使用UserManager方法,我会收到同样的错误。
UserManager.AddClaim(user.AppUser.Id,new Claim(claimGroupItem.MenuItemId.ToString(),claimGroupItem.ClaimValue));
和
await UserManager.UpdateAsync(appUser);
该错误是由以下原因引起的: appUser.Claims.Clear();
如何正确更新用户的声明?
答案 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 });
}