我们扩展了身份用户(ApplicationUser),角色(ApplicationRole)和 UserRole(ApplicationUserRole)。
我们设法保存了对ApplicationUser的更改,但否能够使用以下代码在ApplicationUserRole上保存更改:
public async Task<IActionResult> OnPostAsync(Guid id)
{
if (!ModelState.IsValid)
{
return Page();
}
var userToUpdate = await _context.Users
.FirstOrDefaultAsync(m => m.Id == id.ToString());
var userRoleToUpdate = await _context.UserRoles
.FirstOrDefaultAsync(m => m.UserId == id.ToString());
// null means User was deleted by another user.
if (userToUpdate == null || userRoleToUpdate == null)
{
return await HandleDeletedUser();
}
// Update the RowVersion to the value when this entity was
// fetched. If the entity has been updated after it was
// fetched, RowVersion won't match the DB RowVersion and
// a DbUpdateConcurrencyException is thrown.
// A second postback will make them match, unless a new
// concurrency issue happens.
_context.Entry(userToUpdate)
.Property("RowVersion").OriginalValue = User.RowVersion;
if (await TryUpdateModelAsync<ApplicationUser>(
userToUpdate,
"User",
s => s.FirstName, s => s.LastName, s => s.Email))
{
try
{
await _context.SaveChangesAsync();
if (await TryUpdateModelAsync<ApplicationUserRole>(
userRoleToUpdate,
"UserRole",
s => s.RoleId.ToString()))
{
await _context.SaveChangesAsync();
}
return RedirectToPage("./Index");
}
catch (DbUpdateConcurrencyException ex)
{
var exceptionEntry = ex.Entries.Single();
var clientValues = (ApplicationUser)exceptionEntry.Entity;
var databaseEntry = exceptionEntry.GetDatabaseValues();
if (databaseEntry == null)
{
ModelState.AddModelError(string.Empty, "Unable to save. " +
"The user was deleted by another user.");
return Page();
}
var dbValues = (ApplicationUser)databaseEntry.ToObject();
await setDbErrorMessage(dbValues, clientValues, _context);
// Save the current RowVersion so next postback
// matches unless an new concurrency issue happens.
User.RowVersion = (byte[])dbValues.RowVersion;
// Must clear the model error for the next postback.
ModelState.Remove("User.RowVersion");
}
}
return Page();
}
对此有任何指针吗?我以为我们需要分解保存更改。先是User然后是UserRole,不是吗?
此外,我们没有为 ApplicationUserRole 实施 RowVersion ,我认为这太过头了。
环境: .Net Core 2.1
更新-1:
例外- InvalidOperationException:传递的表达式节点类型'Call'的表达式无效。仅支持模型属性的简单成员访问表达式。
更新-2:
我已更改为此,但没有错误,但角色没有更改:
if (await TryUpdateModelAsync<ApplicationUserRole>(
userRoleToUpdate,
"UserRole",
ur => ur.UserId, ur => ur.RoleId))
{
await _context.SaveChangesAsync();
}
与编辑表单(Edit.html)上的下拉列表中的更新该RoleId相比,我们如何进行映射?!?!
<div class="form-group">
Role:
<select asp-for="User.UserRoles.ElementAt(0).RoleId" class="form-control"
asp-items="@Model.RoleNameSL">
<option value="">-- Select Role --</option>
</select>
<span asp-validation-for="User.UserRoles.ElementAt(0).Role" class="text-danger"></span>
</div>
更新-3:
这很有趣。我将文本从“ UserRole”更改为“”:
if (await TryUpdateModelAsync<ApplicationUserRole>(
userRoleToUpdate,
"",
ur => ur.RoleId))
{
await _context.SaveChangesAsync();
}
现在我们有一个错误,说我认为这已经接近了:
InvalidOperationException:实体类型上的属性'RoleId' 'ApplicationUserRole'是密钥的一部分,因此无法进行修改或 标记为已修改。用以下方法更改现有实体的主体 标识外键首先删除依赖项并调用 然后,“ SaveChanges”将依赖项与新的主体相关联。
是否可能因为我们的ApplicationDBContext中有此对象?在那种情况下,什么是最好的更新方式呢?
protected override void OnModelCreating(ModelBuilder builder)
{
....
// Many to Many relationship - ApplicationUserRole
builder.Entity<ApplicationUserRole>(userRole =>
{
userRole.HasKey(ur => new { ur.UserId, ur.RoleId });
userRole.HasOne(ur => ur.Role)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.RoleId)
.IsRequired();
userRole.HasOne(ur => ur.User)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.UserId)
.IsRequired();
});
}
答案 0 :(得分:1)
如果您使用的外观像AspNetIdentity,则应该能够使用UserManager
更新角色。 UserManager是Identity的一部分,用于管理用户的身份。只要您的角色为AspNetRoles
,然后注入UserManager
就可以将任何用户更新为任何预定义的角色。
添加
private readonly UserManager<ApplicationUser> _userManager;
public Controller(UserManager<ApplicationUser> userManger, ApplicationUser applicationUser)
{
_userManager = userManger;
}
public async Task UpDateRole(string userId)
{
var user = await _userManager.FindByIdAsync(userId);
var result = await _userManager.AddToRoleAsync(userId, "RoleName");
}
应该做您想做的事,您可能还想将该用户从以前的角色中删除。