ASP.NTE MVC 為何IdentityResult ConfirmEmailAsync返回Succeeded總是false的問題排除
最近一直被ASP.NET (.net framework) MVC Identity2 搞得很久
Succeeded總是返回false
明明寄發跟ID和tocken比對都一致就是一直返回false
Succeeded總是返回false
明明寄發跟ID和tocken比對都一致就是一直返回false
終於發現問題點在於
在於我有自己去多設置UserValidate的客製化設定
把這段註解後就恢復正常了...
>~<||| 但我需要這個CustomValidator的客製化設置呀
接續之前此篇
ASP.NET MVC(十一)_ASP.NET Identity使用筆記_初始配置到註冊篇
ASP.NET MVC(十二)_ASP.NET Identity使用筆記_註冊完後的郵件有效性確認
參考此篇建目前還是有問題
將客製化部分加回去研究一下偵錯狀況發現
也有人反映過此issue
主要是因為在做ConfirmEmailAsync 時候又會再跳到
我們自己客製化的CustomUserValidator執行ValidateAsync
此時資料庫已經有此筆record所以又會多判斷導致結果會錯誤判定
這裡稍微調整一下邏輯
首先自動被Identity跟EF創建出來的IdentityDB要記得刪除
等會我們要重新建立
首先針對AspNetUsers資料庫欄位去做一個欄位擴充
去到我們自己新增繼承自IdentityUser的自訂User Class再去做其餘欄位的擴充
public virtual bool IsFirstTimeRequest { get; set; }
有點類似檢查是否為PostBack那種概念
我希望他只要在第一次Request時候再做這個Validate查檢就好了
雖說官方設計認為每次都要觸發這個查檢機制是正常的
但會與我們資料庫互動檢查有衝突
User.cs
預設默認在建構子就給定預設值為true
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; using System; using System.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading.Tasks; using System.Web; namespace AgricultureManagementSystem.Models { public class User : IdentityUser { public virtual string Account { get; set; } public virtual string Region { get; set; } public virtual bool IsFirstTimeRequest { get; set; } public User() { this.IsFirstTimeRequest = true; } public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } } } |
之後再去我們自訂的CustomUserValidator.cs中
針對ValidateAsync的override 方法中做邏輯調整
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public override async Task<IdentityResult> ValidateAsync(User user) { IdentityResult result = await base.ValidateAsync(user); if (user.IsFirstTimeRequest) { int cntAccount = _userManager.Users.Where(n => n.Account == user.Account).Count(); if (cntAccount > 0) { var errors = result.Errors.ToList(); //errors.Add("This Account Name already exists"); result = new IdentityResult(errors); } } return result; } |
Email驗證的Action
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | [HttpGet] [AllowAnonymous] public async Task<ActionResult> ConfirmEmail(string userId, string code) { if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(code)) { return View("Error"); } var _user = await UserManager.FindByIdAsync(userId); if (_user == null) { return View("Error"); } _user.IsFirstTimeRequest = false; await UserManager.UpdateAsync(_user); var result = await UserManager.ConfirmEmailAsync(userId, code); return View(result.Succeeded ? "ConfirmEmail" : "Error"); } |
最終就可以讓email驗證機制運行正確
Ref:
ConfirmEmailAsync in UserManager does a ton of unrelated actions and validations
Entity Framework 6 Code first Default value
ASP.NET Identity 2.1 Accounts Confirmation, and Password Policy Configuration – Part 2
Asp.NET Identity 2 giving “Invalid Token” error
ASP MVC ConfirmEmailAsync not working
ConfirmEmailAsync() method is not working
留言
張貼留言