asp.net-mvc - tables - asp.net identity web api
ActualizaciĆ³n de datos de usuario: identidad de ASP.NET (11)
He agregado campos personalizados a la clase ApplicationUser
También creé un formulario a través del cual el usuario puede ingresar / editar los campos.
Sin embargo, por alguna razón, no puedo actualizar los campos en la base de datos.
[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");
}
Mi problema es similar a las propiedades personalizadas de MVC5 ApplicationUser , pero parece que usa una versión anterior de Identity porque la clase IdentityManager no parece existir.
¿Alguien puede guiarme sobre cómo actualizar User
información del User
en la base de datos?
ACTUALIZACIÓN: si incluyo todos los campos en el formulario de registro, todos los valores se almacenan en el campo apropiado en un nuevo registro de la tabla Users
de la base de datos.
No sé hacer cambios en los campos de un usuario existente (fila en la tabla de users
). UserManager.UpdateAsync(user)
no funciona.
También tenga en cuenta que mi problema está más orientado a la identidad que EntityFramework
¡¡¡Excelente!!!
IdentityResult result = await UserManager.UpdateAsync(user);
Agregue el siguiente código a su archivo Startup.Auth.cs en el constructor estático:
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
};
La línea de código de configuración UserManagerFactory es lo que usa para asociar su DataContext personalizado con el UserManager. Una vez hecho esto, puede obtener una instancia del UserManager en su ApiController y el método UserManager.UpdateAsync (usuario) funcionará porque está usando su DataContext para guardar las propiedades adicionales que ha agregado a su usuario de aplicación personalizado.
Basado en su pregunta y también anotado en el comentario.
¿Alguien puede guiarme sobre cómo actualizar la información del usuario en la base de datos?
Sí, el código es correcto para actualizar cualquier ApplicationUser
a la base de datos.
IdentityResult result = await UserManager.UpdateAsync(user);
- Verificar restricciones de todos los valores requeridos del campo
- Compruebe si UserManager se crea con ApplicationUser.
UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
El UserManager no funcionó, y As @Kevin Junghans escribió:
UpdateAsync solo confirma la actualización del contexto, aún necesita guardar el contexto para que se comprometa con la base de datos
Aquí hay una solución rápida (antes de las nuevas características en ASP.net identity v2) que utilicé en un proyecto de formularios web. los
class AspNetUser :IdentityUser
Se migró desde SqlServerMembership aspnet_Users. Y el contexto está definido:
public partial class MyContext : IdentityDbContext<AspNetUser>
Pido disculpas por la reflexión y el código síncrono: si lo pones en un método asíncrono, utiliza await
para las llamadas asincrónicas y elimina las tareas y Wait () s. The arg, props, contiene los nombres de las propiedades para actualizar.
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();
}
El contexto OWIN le permite obtener el contexto db. Parece que funciona bien hasta ahora, y después de todo, obtuve la idea de la clase ApplciationUserManager que hace lo mismo.
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();
}
Esto funciona para mí Estoy usando Identity 2.0, parece que GetApplicationUser ya no está allí.
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);
Estoy usando el nuevo EF & Identity Core y tengo el mismo problema, con la adición de que tengo este error:
La instancia del tipo de entidad no se puede rastrear porque ya se está rastreando otra instancia de este tipo con la misma clave.
Con el nuevo modelo DI agregué el controlador del constructor al contexto de la base de datos.
Traté de ver cuál es el conflicto con _conext.ChangeTracker.Entries()
y AsNoTracking()
a mis llamadas sin éxito.
Solo necesito cambiar el estado de mi objeto (en este caso, Identidad)
_context.Entry(user).State = EntityState.Modified;
var result = await _userManager.UpdateAsync(user);
Y funcionó sin crear otra tienda u objeto y mapeo.
Espero que alguien más sea útil a mis dos centavos.
He intentado la funcionalidad de la misma manera y cuando llamo UserManager.Updateasync
método UserManager.Updateasync
, tiene éxito pero no hay ninguna actualización en la base de datos. Después de pasar algún tiempo, encontré otra solución para actualizar los datos en la tabla aspnetusers
, que es la siguiente:
1) necesitas crear UserDbContext
clase UserDbContext
heredando de la clase IdentityDbContext
como esta:
public class UserDbContext:IdentityDbContext<UserInfo>
{
public UserDbContext():
base("DefaultConnection")
{
this.Configuration.ProxyCreationEnabled = false;
}
}
2) luego en la información de usuario de la actualización del controlador de cuenta como esta:
UserDbContext userDbContext = new UserDbContext();
userDbContext.Entry(user).State = System.Data.Entity.EntityState.Modified;
await userDbContext.SaveChangesAsync();
donde el user
es su entidad actualizada.
Espero que esto te ayudará.
OK ... Pasé horas tratando de entender por qué userManager.updateAsync
no persistiría en los datos del usuario que editamos ... hasta que llegue a la siguiente conclusión:
La confusión surge del hecho de que creamos el UserManager
en una línea como esta:
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyDbContext()));
... luego usamos manager.UpdateAsync( user );
pero eso actualizará al usuario en el contexto, y luego necesitaremos guardar los cambios en el contexto db de la identidad. Entonces, la pregunta es cómo obtener el Identity DBcontext de la manera más fácil.
Para solucionar esto, no deberíamos crear el UserManager
en una línea ... y así es como lo hago:
var store = new UserStore<ApplicationUser>(new MyDbContext());
var manager = new UserManager(store);
luego de actualizar al usuario llamando
manager.UpdateAsync(user);
entonces vas al contexto
var ctx = store.context;
entonces
ctx.saveChanges();
wahooooooo ... persistió :)
Espero que esto ayude a alguien que tiró de su cabello por unas horas: P
Si deja null alguno de los campos para ApplicationUser O IdentityUser null, la actualización volverá a tener éxito pero no guardará los datos en la base de datos.
Ejemplo de solución:
ApplicationUser model = UserManager.FindById(User.Identity.GetUserId())
Agregue los campos recién actualizados:
model.Email = AppUserViewModel.Email;
model.FName = AppUserViewModel.FName;
model.LName = AppUserViewModel.LName;
model.DOB = AppUserViewModel.DOB;
model.Gender = AppUserViewModel.Gender;
Llamar a UpdateAsync
IdentityResult result = await UserManager.UpdateAsync(model);
Lo he probado y funciona.
También tuve problemas al utilizar UpdateAsync al desarrollar una versión de SimpleSecurity que utiliza ASP.NET Identity. Por ejemplo, agregué una función para restablecer la contraseña que necesitaba agregar un token de restablecimiento de contraseña a la información del usuario. Al principio intenté usar UpdateAsync y obtuve los mismos resultados que tú. Terminé envolviendo la entidad de usuario en un patrón de repositorio y lo puse a funcionar. Puede ver el proyecto SimpleSecurity para ver un ejemplo . Después de trabajar con ASP.NET Identity más (la documentación aún no existe), creo que UpdateAsync solo confirma la actualización del contexto, aún necesita guardar el contexto para que se comprometa con la base de datos.