Good all! At the moment, the problem is solved, but I do not like the way to solve it. Also, I do not understand why the previous version did not work. Now in order. There is a website, when registering on which you need to confirm email. The letter arrives, the link is working.

[HttpPost] [ValidateAntiForgeryToken] public ActionResult Register(DataModels.RegisterViewModel model, HttpPostedFileBase files) { if (!ModelState.IsValid) return View(model); string path = null; if (files != null && files.ContentLength > 0) { string filename = model.Login + ".jpg"; path = Path.Combine(Server.MapPath("/App_Data/temp/Users"), filename); Random rnd = new Random(113); if (System.IO.File.Exists(path)) path = path + rnd.Next(99999); files.SaveAs(path); model.Photo = System.IO.File.ReadAllBytes(path); } try { if (path != null) System.IO.File.Delete(path); } catch (IOException){ /* ignored*/ } var user = CacheManager.CreateUser(model); if (user == null) { ModelState.AddModelError("", Resources.UserAlreadyExist); return View(model); } if (!SendVerificationEmail(user)) ModelState.AddModelError("", Resources.EmailSendingErr); return RedirectToAction("VerifyEmail", new {user.UserID}); } public ActionResult VerifyEmail(int userid) { var user = CacheManager.GetUser(userid); ViewData.Model = user; return View(); } [HttpPost] public ActionResult VerifyEmail(BlogUser user) { if (!ModelState.IsValid) View(user); if (user != null) { if (!SendVerificationEmail(user)) ModelState.AddModelError("", Resources.EmailSendingErr); else return RedirectToAction("VerifyEmail", new {user.UserID}); } else ModelState.AddModelError("", Resources.UserNotExist); return View(); } 

Now about the ConfirmEmail method. Not working option:

  [AllowAnonymous] public ActionResult ConfirmEmail(int token, string email) { var user = CacheManager.GetUser(Convert.ToInt32(token)); if (user == null) return RedirectToAction("Register"); if (user.Email != email) return RedirectToAction("VerifyEmail", new { user.UserID }); user.Verified = 1; CacheManager.SaveUser(user, false); return View("Login"); } 

What does it mean non-working: I click on the link, the backcode is executed and I transfer to the login page, great, and it was necessary. I enter the username and password, and oh Miracle! - I entered, cool. I press the exit. Trying to go again - it turns out. I restart the project, try to log in - returns the login page with an error saying that the email is not confirmed (this should be the case for users who have not confirmed the email). I climb into the base and see that the value is verified = 0. It turns out that before this change, the entities were only stored in the cache. Now, for clarity, two more methods from the project are worth citing. Class CacheManager method SaveUser:

  public static BlogUser SaveUser(BlogUser user, bool hashPass) { return Rep.SaveUser(new BlogUser { Name = user.Name, Surname = user.Surname, Patronymic = user.Patronymic, UserLogin = user.UserLogin, Password = hashPass ? Hash(user.Password) : user.Password, Email = user.Email, UserPhoto = user.UserPhoto, UserID = user.UserID, RegistrationDate = user.RegistrationDate, UserRight = user.UserRight, Blocked = user.Blocked, Warnings = user.Warnings, Verified = user.Verified }); } 

Do not pay attention to hashPass, because sometimes I need to hash the password, and sometimes not. Now the SaveUser method of the Repository class:

  public BlogUser SaveUser(BlogUser user) { if (user.UserID == 0) _db.BlogUser.Add(user); else { _db.BlogUser.Attach(_db.BlogUser.Single(u => u.UserID == user.UserID)); ((IObjectContextAdapter) _db).ObjectContext.ApplyCurrentValues("BlogUser", user); } _db.SaveChanges(); CacheManager.PurgeCacheItems("users"); return GetUser(user.UserID); } 

It would seem that everything is good and should work, but no - the problem described above holds. As I understand it, the changes are not saved in the entity itself, but in its copy in the cache. In this case, all the code related to the cache passes - debug and watched every object deleted from / added to the cache. _db.SaveChanges also works and throws no exceptions. Now about the working version. I only changed the ConfirmEmail method and it all worked:

  [AllowAnonymous] public ActionResult ConfirmEmail(int token, string email) { var user = CacheManager.GetUser(Convert.ToInt32(token)); if (user == null) return RedirectToAction("Register"); if (user.Email != email) return RedirectToAction("VerifyEmail", new { user.UserID }); CacheManager.SaveUser(new BlogUser { Blocked = 0, Email = user.Email, Password = user.Password, Verified = 1, UserID = user.UserID, Name = user.Name, Surname = user.Surname, Patronymic = user.Patronymic, UserRight = user.UserRight, Warnings = 0, UserLogin = user.UserLogin, UserPhoto = user.UserPhoto, RegistrationDate = user.RegistrationDate }, false); return View("Login"); } 

The same problem was observed, for example, with a change in the number of user requests for the current day of a letter with password recovery. In this case, the first request got into the database, but with the second, and so on. RequestsToday value has not changed. Decided in a similar way.

Explain kind to me, fool old why this happens. The current solution does not suit me by the fact that I essentially create two identical user instances at two levels.

  • What does it have to do with SQL Server? - Slava Murygin 8:51 pm
  • @Slava Murygin, well, if you think about it, you can guess that the MSSQL database is used. In general, I put the MSSQL tag, but apparently missed the server - sky49rus
  • Yes, she was, so I got here. Looks like she was cleaned and served right. The question has nothing to do with it. - Slava Murygin

0