首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在UserRole内核2中更新身份用户角色的扩展.NET

如何在UserRole内核2中更新身份用户角色的扩展.NET
EN

Stack Overflow用户
提问于 2018-12-25 23:14:25
回答 1查看 2.2K关注 0票数 0

我们有一个扩展的标识用户(ApplicationUser)Role (ApplicationRole)UserRole (ApplicationUserRole)

我们设法为ApplicationUser保存更改,但而不是能够使用以下代码在ApplicationUserRole上保存更改:

代码语言:javascript
复制
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();


    }

有这个指针吗?我以为我们需要分解保存更改。首先是用户,然后是UserRole,不是吗?

另外,我们没有为ApplicationUserRole实现RowVersion,我认为这太过分了。

Environment: .Net Core 2.1

更新- 1:

异常- InvalidOperationException:传递的表达式节点类型'Call‘的表达式无效。只支持模型属性的简单成员访问表达式。

更新- 2:

我已更改为此,没有错误,但角色没有更改:

代码语言:javascript
复制
if (await TryUpdateModelAsync<ApplicationUserRole>(
                   userRoleToUpdate,
                   "UserRole",
                   ur => ur.UserId, ur => ur.RoleId))
                {
                    await _context.SaveChangesAsync();
                }

如何映射与从下拉列表中更新此RoleId有关的工作,如编辑表单(Edit.html)?!!

代码语言:javascript
复制
<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“改为"":

代码语言:javascript
复制
if (await TryUpdateModelAsync<ApplicationUserRole>(
                   userRoleToUpdate,
                   "",
                   ur => ur.RoleId))
                {
                    await _context.SaveChangesAsync();
                }

现在,我们有一个错误的说法,我认为这是接近:

InvalidOperationException:实体类型'ApplicationUserRole‘上的属性'RoleId’是键的一部分,因此不能修改或标记为修改。若要用标识外键更改现有实体的主体,首先删除依赖项并调用'SaveChanges‘,然后将依赖项与新主体关联。

这有可能是因为我们的ApplicationDBContext中有这个吗?在这种情况下,那么更新这个程序的最佳方法是什么?

代码语言:javascript
复制
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();
        });
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-26 18:59:25

如果您使用的是AspNetIdentity (看起来是这样的),那么您应该能够使用UserManager更新角色。UserManager是标识的一部分,用于管理用户的标识。只要您的角色是AspNetRoles,那么注入UserManager将允许您将任何用户更新为任何预定义的角色。

添加

代码语言:javascript
复制
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");
}

如果您想做什么,您也可能希望将该用户从他们以前所在的角色中删除。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53926220

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档