Sorry for my english, I'll do it as well as I can.
I have the Entity "Usuario" which receives from the rbacManager the object, calling Login method (see below). This method, as you can see, throws an exception when it can't match both the user an password. In this case, I have to increment the property Intentos, to allow users to have only three opportunities to fail.
The problem is the following: SaveChanges method is not saving the values modified in Usuario. I think that SaveChanges method is failing due to the exception, but i'm not sure. I couldn't find any help on the web.
This is the action Method LogOn:
using(EntitiesModel dbContext = new EntitiesModel())
{
try
{
string hPassword = FormsAuthentication.HashPasswordForStoringInConfigFile(model.Password, "SHA1");
Usuario usuario = this.rbacManager.Login(model.UserName, hPassword);
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
&& !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
{
return Redirect(returnUrl);
}
else
return RedirectToAction("Index", "Home");
}
catch (LoginIncorrectoException)
{
dbContext.SaveChanges();
ViewData["Message"] = "User incorrect.";
}
catch (UsuarioBloqueadoException)
{
ViewData["Message"] = "User locked";
}
return View(model);
}
And the method Login of the fourth line, that throws the exception:
using (EntitiesModel context = new EntitiesModel())
{
Usuario usuario = this.GetUsuario(username);
if (usuario == null)
throw new LoginIncorrectoException();
if (!usuario.EstaActivo())
{
throw new UsuarioBloqueadoException();
}
if (usuario.Password != password)
{
usuario.Intentos++;
if (usuario.Intentos >= 3)
{
usuario.Activo = false;
context.SaveChanges();
throw new UsuarioBloqueadoException();
}
else
{
context.SaveChanges();
throw new LoginIncorrectoException();
}
}
usuario.Intentos = 0;
return usuario;
}
EDIT: I copy GetUsuario method.
private Usuario GetUsuario(string username)
{
using (EntitiesModel context = new EntitiesModel())
{
List<Usuario> Usuarios = context
.Usuarios
.Where(x => x.Username == username)
.ToList();
if (Usuarios.Count == 1)
return Usuarios.First();
else
throw null;
}
}
Anyone knows why SaveChanges is not working? Thanks!
Your problem is with the fact that each method is creating and disposing its own DbContext. So when the GetUser call returns the User object it is detached from the DbContext because you've disposed of it. Changes to that User object will now not be saved. The most immediate fix is to pass the EntitiesModel created in the Login method to the GetUser method. Of course there are better Unit Of Work patterns that you should research and implement, but this should get you across the immediate hurdle. You could also Attach the User object returned by the GetUser call to the EntitiesModel created inside the Login call.