asp.net-mvc 更新用户数据 - ASP.NET Identity
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20444022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Updating user data - ASP.NET Identity
提问by gldraphael
I've added custom fields to the ApplicationUserclass
I've also created a form through which the user can enter/edit the fields.
However for some reason I'm not able to update the fields in the database.
我已经向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");
}
My problem is similar to MVC5 ApplicationUser custom properties, but that seems to use an older version of Identity because the IdentityManager class doesn't seem to exist.
我的问题类似于MVC5 ApplicationUser custom properties,但似乎使用了旧版本的 Identity 因为 IdentityManager 类似乎不存在。
Can someone guide me on how to update Userinfo in the database?
有人可以指导我如何更新User数据库中的信息吗?
UPDATE:
If I include all the fields in the register form, all the values are stored in the appropriate field in a new record of the Userstable from the database.
更新:如果我在注册表中包含所有字段,则所有值都存储在Users数据库表的新记录中的相应字段中。
I don't know to make changes to the fields of an existing user (row in the userstable). UserManager.UpdateAsync(user)doesn't work.
我不知道对现有用户的字段(users表中的行)进行更改。UserManager.UpdateAsync(user)不起作用。
Also note my issue is more Identity oriented than EntityFramework
另请注意,我的问题比 EntityFramework 更面向身份
回答by stackunderflow
OK... I spent hours trying to figure why userManager.updateAsyncwould not persist the user data that we edit ... until I reached the following conclusion:
好的...我花了几个小时试图弄清楚为什么userManager.updateAsync不保留我们编辑的用户数据...直到我得出以下结论:
The confusion arises from the fact that we create the UserManagerin one line like this:
混乱源于我们UserManager在一行中创建这样的事实:
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDbContext()));
...then we use manager.UpdateAsync( user );but that will update the user in the context, and then we will need to save changes to the dbcontext of the Identity. So, the question is how to get the Identity DBcontext in the easiest way.
...然后我们使用manager.UpdateAsync( user );但是这将更新上下文中的用户,然后我们需要保存对身份的 dbcontext 的更改。所以,问题是如何以最简单的方式获取 Identity DBcontext。
To solve this, we should not create the UserManagerin one line ... and here is how I do it:
为了解决这个问题,我们不应该UserManager在一行中创建......我是这样做的:
var store = new UserStore<ApplicationUser>(new MyDbContext());
var manager = new UserManager(store);
then after updating the user by calling
然后通过调用更新用户后
manager.UpdateAsync(user);
then you go to the context
然后你去上下文
var ctx = store.context;
then
然后
ctx.saveChanges();
wahooooooo...persisted :)
哇哦哦...坚持:)
Hope this will help someone who pulled their hair for a few hours :P
希望这能帮助那些拉了几个小时头发的人:P
回答by JoshdeVries
If you leave any of the fields for ApplicationUser OR IdentityUser nullthe update will come back as successful but wont save the data in the database.
如果你留下任何的ApplicationUser或IdentityUser领域的空更新会回来的成功,但不会保存在数据库中的数据。
Example solution:
示例解决方案:
ApplicationUser model = UserManager.FindById(User.Identity.GetUserId())
Add the newly updated fields:
添加新更新的字段:
model.Email = AppUserViewModel.Email;
model.FName = AppUserViewModel.FName;
model.LName = AppUserViewModel.LName;
model.DOB = AppUserViewModel.DOB;
model.Gender = AppUserViewModel.Gender;
Call UpdateAsync
调用更新异步
IdentityResult result = await UserManager.UpdateAsync(model);
I have tested this and it works.
我已经测试过这个并且它有效。
回答by Atters
The OWIN context allows you to get the db context. Seems to be working fine so far me, and after all, I got the idea from the ApplciationUserManager class which does the same thing.
OWIN 上下文允许您获取 db 上下文。到目前为止我似乎工作得很好,毕竟,我从 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();
}
回答by subsci
The UserManager did not work, and As @Kevin Junghans wrote,
UserManager 不起作用,正如@Kevin Junghans 所写,
UpdateAsync just commits the update to the context, you still need to save the context for it to commit to the database
UpdateAsync 只是将更新提交到上下文,您仍然需要保存上下文以将其提交到数据库
Here is quick solution (prior to new features in ASP.net identity v2) I used in a web forms projetc. The
这是我在 web 表单项目中使用的快速解决方案(在 ASP.net identity v2 中的新功能之前)。这
class AspNetUser :IdentityUser
Was migrated from SqlServerMembership aspnet_Users. And the context is defined:
从 SqlServerMembership aspnet_Users 迁移。并定义了上下文:
public partial class MyContext : IdentityDbContext<AspNetUser>
I apologize for the reflection and synchronous code--if you put this in an async method, use awaitfor the async calls and remove the Tasks and Wait()s. The arg, props, contains the names of properties to update.
我为反射和同步代码道歉——如果你把它放在一个异步方法中,await用于异步调用并删除 Tasks 和 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();
}
回答by Kevin Junghans
I also had problems using UpdateAsync when developing a version of SimpleSecuritythat uses ASP.NET Identity. For example, I added a feature to do a password reset that needed to add a password reset token to the user information. At first I tried using UpdateAsync and it got the same results as you did. I ended up wrapping the user entity in a repository pattern and got it to work. You can look at the SimpleSecurity project for an example. After working with ASP.NET Identity more (documentation is still non-existent) I think that UpdateAsync just commits the update to the context, you still need to save the context for it to commit to the database.
在开发使用 ASP.NET Identity的SimpleSecurity版本时,我在使用 UpdateAsync 时也遇到了问题。例如,我添加了一个功能来进行密码重置,需要将密码重置令牌添加到用户信息中。起初我尝试使用 UpdateAsync,它得到了和你一样的结果。我最终将用户实体包装在存储库模式中并使其工作。您可以查看SimpleSecurity 项目以获取示例。在更多地使用 ASP.NET Identity(文档仍然不存在)之后,我认为 UpdateAsync 只是将更新提交到上下文,您仍然需要保存上下文以将其提交到数据库。
回答by Ankit Sahrawat
I have tried the functionality in the same way and when i call UserManager.Updateasyncmethod it succeeds but there is no update in the database. After spending some time i found another solution to update the data in aspnetuserstable which is following:
我以相同的方式尝试了该功能,当我调用UserManager.Updateasync方法时它成功了,但数据库中没有更新。花了一些时间后,我找到了另一种更新aspnetusers表中数据的解决方案,如下所示:
1) you need to create UserDbContextclass inheriting from IdentityDbContextclass like this:
1)您需要创建UserDbContext从IdentityDbContext类继承的类,如下所示:
public class UserDbContext:IdentityDbContext<UserInfo>
{
public UserDbContext():
base("DefaultConnection")
{
this.Configuration.ProxyCreationEnabled = false;
}
}
2) then in Account controller update user information like this:
2)然后在帐户控制器中更新用户信息,如下所示:
UserDbContext userDbContext = new UserDbContext();
userDbContext.Entry(user).State = System.Data.Entity.EntityState.Modified;
await userDbContext.SaveChangesAsync();
where useris your updated entity.
user你更新的实体在哪里。
hope this will help you.
希望这会帮助你。
回答by Max
Excellent!!!
优秀!!!
IdentityResult result = await UserManager.UpdateAsync(user);
回答by jd4u
Based on your question and also noted in comment.
根据您的问题,并在评论中注明。
Can someone guide me on how to update User info in the database?
有人可以指导我如何更新数据库中的用户信息吗?
Yes, the code is correct for updating any ApplicationUserto the database.
是的,代码对于将任何更新ApplicationUser到数据库是正确的。
IdentityResult result = await UserManager.UpdateAsync(user);
IdentityResult result = await UserManager.UpdateAsync(user);
- Check for constrains of all field's required values
- Check for UserManager is created using ApplicationUser.
- 检查所有字段所需值的约束
- 检查 UserManager 是使用 ApplicationUser 创建的。
UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
回答by Yan
This works for me. I'm using Identity 2.0, it looks like GetApplicationUser isn't there anymore.
这对我有用。我正在使用 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);
回答by Ivan Paniagua
I am using the new EF & Identity Core and I have the same issue, with the addition that I've got this error:
我正在使用新的 EF & Identity Core 并且我遇到了同样的问题,另外还有这个错误:
The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked.
无法跟踪实体类型的实例,因为已在跟踪具有相同键的此类型的另一个实例。
With the new DI model I added the constructor's Controller the context to the DB.
使用新的 DI 模型,我将构造函数的 Controller 上下文添加到数据库中。
I tried to see what are the conflict with _conext.ChangeTracker.Entries()and adding AsNoTracking()to my calls without success.
我试图查看与我的通话有什么冲突_conext.ChangeTracker.Entries()并添加AsNoTracking()到我的通话中,但没有成功。
I only need to change the state of my object (in this case Identity)
我只需要更改对象的状态(在本例中为 Identity)
_context.Entry(user).State = EntityState.Modified;
var result = await _userManager.UpdateAsync(user);
And worked without create another store or object and mapping.
并且无需创建另一个存储或对象和映射即可工作。
I hope someone else is useful my two cents.
我希望别人对我的两分钱有用。

