更新用户数据 - ASP.NET 标识



我已将自定义字段添加到ApplicationUser
中我还创建了一个表单,用户可以通过该表单输入/编辑字段。
但是由于某种原因,我无法更新数据库中的字段。

[HttpPost]
[ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Manage(EditProfileViewModel model)
{
    if (ModelState.IsValid)
    {
        // Get the current application user
        var user = User.Identity.GetApplicationUser();
        // Update the details
        user.Name = new Name { First = model.FirstName, Last = model.LastName, Nickname = model.NickName };
        user.Birthday = model.Birthdate;
        // This is the part that doesn't work
        var result = await UserManager.UpdateAsync(user);
        // However, it always succeeds inspite of not updating the database
        if (!result.Succeeded)
        {
            AddErrors(result);
        }
    }
    return RedirectToAction("Manage");
}

我的问题类似于MVC5 ApplicationUser自定义属性,但这似乎使用旧版本的Identity,因为IdentityManager类似乎不存在。

有人可以指导我如何更新数据库中User信息吗?

更新:如果我在注册表单中包含所有字段,则所有值都存储在数据库中Users表的新记录中的相应字段中。

我不知道要更改现有用户的字段(users表中的行(。 UserManager.UpdateAsync(user)不起作用。

另请注意,我的问题比实体框架更面向身份

好的...我花了几个小时试图弄清楚为什么userManager.updateAsync不会保留我们编辑的用户数据......直到我得出以下结论:

混淆源于我们在一行中创建UserManager,如下所示:

var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDbContext()));

。然后我们使用manager.UpdateAsync( user );但这将更新上下文中的用户,然后我们需要将更改保存到 Identity 的 dbcontext。因此,问题是如何以最简单的方式获取身份数据库上下文。

为了解决这个问题,我们不应该在一行中创建UserManager......这是我的做法:

var store = new UserStore<ApplicationUser>(new MyDbContext());
var manager = new UserManager(store);

然后在通过调用更新用户后

manager.UpdateAsync(user);

然后你转到上下文

var ctx = store.context;

然后

ctx.saveChanges();

呜...持久:)

希望这能帮助那些拉头发几个小时的人:P

如果保留 ApplicationUser OR IdentityUser null 的任何字段,则更新将返回为成功,但不会将数据保存在数据库中。

示例解决方案:

ApplicationUser model = UserManager.FindById(User.Identity.GetUserId())

添加新的字段:

model.Email = AppUserViewModel.Email;
model.FName = AppUserViewModel.FName;
model.LName = AppUserViewModel.LName;
model.DOB = AppUserViewModel.DOB;
model.Gender = AppUserViewModel.Gender;

调用更新异步

IdentityResult result = await UserManager.UpdateAsync(model);

我已经对此进行了测试,并且有效。

OWIN 上下文允许您获取数据库上下文。到目前为止,我似乎工作正常,毕竟,我从ApplciationUserManager类中得到了做同样事情的想法。

    internal void UpdateEmail(HttpContext context, string userName, string email)
    {
        var manager = context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var user = manager.FindByName(userName);
        user.Email = email;
        user.EmailConfirmed = false;
        manager.Update(user);
        context.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();
    }

用户管理器不起作用,正如荣汉斯@Kevin所写,

UpdateAsync 只是将更新提交到上下文,您仍然需要保存上下文以将其提交到数据库

这是我在 Web 表单项目中使用的快速解决方案(在 ASP.net 标识 v2 中的新功能之前(。这

class AspNetUser :IdentityUser

是从 SqlServerMembership aspnet_Users 迁移而来的。上下文被定义:

public partial class MyContext : IdentityDbContext<AspNetUser>

对于反射和同步代码,我深表歉意 - 如果您将其放在异步方法中,请使用await进行异步调用并删除任务和Wait((s。参数 props 包含要更新的属性的名称。

 public static void UpdateAspNetUser(AspNetUser user, string[] props)
 {
     MyContext context = new MyContext();
     UserStore<AspNetUser> store = new UserStore<AspNetUser>(context);
     Task<AspNetUser> cUser = store.FindByIdAsync(user.Id); 
     cUser.Wait();
     AspNetUser oldUser = cUser.Result;
    foreach (var prop in props)
    {
        PropertyInfo pi = typeof(AspNetUser).GetProperty(prop);
        var val = pi.GetValue(user);
        pi.SetValue(oldUser, val);
    }
    Task task = store.UpdateAsync(oldUser);
    task.Wait();
    context.SaveChanges();
 }
我在

开发使用 ASP.NET Identity的SimpleSecurity版本时也遇到了使用UpdateAsync的问题。例如,我添加了一项功能来执行密码重置,该功能需要向用户信息添加密码重置令牌。起初我尝试使用UpdateAsync,它得到了与您相同的结果。我最终将用户实体包装在存储库模式中并使其工作。 您可以查看 SimpleSecurity 项目作为示例。在更多地使用 ASP.NET Identity(文档仍然不存在(之后,我认为UpdateAsync只是将更新提交到上下文中,您仍然需要保存上下文以将其提交到数据库。

我以相同的方式尝试了该功能,当我调用该方法时UserManager.Updateasync它成功了,但数据库中没有更新。花了一些时间后,我找到了另一种解决方案来更新表中aspnetusers数据,如下所示:

1(你需要像这样创建从类继承UserDbContextIdentityDbContext类:

public class UserDbContext:IdentityDbContext<UserInfo>
{
    public UserDbContext():
        base("DefaultConnection")
    {
        this.Configuration.ProxyCreationEnabled = false;
    }
}

2(然后在帐户控制器中更新用户信息,如下所示:

UserDbContext userDbContext = new UserDbContext();
userDbContext.Entry(user).State = System.Data.Entity.EntityState.Modified;
await userDbContext.SaveChangesAsync();

其中user是更新的实体。

希望这对你有帮助。

优秀!!

IdentityResult result = await UserManager.UpdateAsync(user);

根据您的问题并在评论中注明。

有人可以指导我如何更新数据库中的用户信息吗?

是的,该代码对于更新数据库的任何ApplicationUser是正确的。

IdentityResult result = await UserManager.UpdateAsync(user);

  • 检查所有字段所需值的约束
  • 检查用户管理器是使用应用程序用户创建的。

UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

这对

我有用。我正在使用Identity 2.0,看起来GetApplicationUser不再存在。

        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
        if (!string.IsNullOrEmpty(form["FirstName"]))
        {
            user.FirstName = form["FirstName"];
        }
        if (!string.IsNullOrEmpty(form["LastName"]))
        {
            user.LastName = form["LastName"];
        }
        IdentityResult result = await UserManager.UpdateAsync(user);

我正在使用新的EF和Identity Core,但我遇到了同样的问题,另外我遇到了这个错误:

无法跟踪实体类型的实例,因为另一个实例 具有相同密钥的此类型已被跟踪。

使用新的 DI 模型,我将构造函数的控制器上下文添加到数据库中。

我试图看看与_conext.ChangeTracker.Entries()有什么冲突,并在我的电话中添加AsNoTracking(),但没有成功。

我只需要更改对象的状态(在本例中为标识(

_context.Entry(user).State = EntityState.Modified;
var result = await _userManager.UpdateAsync(user);

并且无需创建另一个商店或对象和映射即可工作。

我希望别人对我的两分钱有用。

将以下代码添加到静态构造函数下的 Startup.Auth.cs 文件中:

        UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };

UserManagerFactory 設定的碼行是用來將自訂 DataContext 與 UserManager 聯繫起來的。 完成此操作后,您可以在 ApiController 中获取 UserManager 的实例,并且 UserManager.UpdateAsync(user( 方法将起作用,因为它使用 DataContext 来保存您添加到自定义应用程序用户的额外属性。

我使用的是.Net Core 3.1或更高版本。请遵循解决方案:

  public class UpdateAssignUserRole
    {
        public string username { get; set; }
        public string rolename { get; set; }
        public bool IsEdit { get; set; }
    }
 private async Task UpdateSeedUsers(UserManager<IdentityUser> userManager, UpdateAssignUserRole updateassignUsername)
        {
            IList<Users> Users = await FindByUserName(updateassignUsername.username);
            if (await userManager.FindByNameAsync(updateassignUsername.username) != null)
            {
                var user = new IdentityUser
                {
                    UserName = updateassignUsername.username,
                    Email = Users[0].Email,
 
                };
                var result = await userManager.FindByNameAsync(updateassignUsername.username);
                if (result != null)
                {
                    IdentityResult deletionResult = await userManager.RemoveFromRolesAsync(result, await userManager.GetRolesAsync(result));
                    if (deletionResult != null)
                    {
                        await userManager.AddToRoleAsync(result, updateassignUsername.rolename);
                    }
                }
            }
        }

相关内容

  • 没有找到相关文章

最新更新