0

我有一個Web應用程序,我正在使用ASP.NET身份2聲明爲網站用戶的訪問控制列表。我在ApplicationUser模型中有正確的所有聲明,它有一個聲明列表。ASP.NET EF6身份2更新用戶聲明更新爲用戶錯誤

我想清除用戶的索賠,然後給他們一整套新的。 我有一個包含索賠項目

[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. 我想刪除,添加和保存在ApplicationUser索賠。 Claims對象不使用UserManager方法。 (ApplicationUser包含對用戶的引用)。
  2. 我有一個try catch塊,因爲它拋出了一些驗證錯誤。 散發出來的痕跡的錯誤信息是:

Class: System.Data.Entity.DynamicProxies.IdentityUserClaim_FCA22938ED9E4AAF12F5F2E4717CA49CC6F53B512CF2A371AA0C95D210D35870, Property: UserId, Error: The UserId field is required.

  • 如果我嘗試和使用的UserManager方法,我得到了同樣的錯誤。

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

  • await UserManager.UpdateAsync(appUser); 
    

    該錯誤是由這引起被稱爲: appUser.Claims.Clear();

    如何正確更新用戶的聲明?

    回答

    0

    我明白了。出於某種原因appUser.Claims.Clear()不工作,並導致userId爲空錯誤。所以我已經在循環中手動刪除了舊的聲明,現在它全部正常工作。

    [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 }); 
    } 
    
    +0

    ...你會介意把你的ApplicationUser類放在原始文章中,讓人們更好地理解問題和解決方案。 – dinotom 2017-11-13 01:51:10