如何在同一个AccountController中用UserManager和SignInManager实现多注册登录表单?
血库项目中为ReciptionBank实现注册登录功能(基于现有AccountController)
我正在开发血库项目,当前AccountController已实现Donor(献血者)的注册与登录功能,现希望在同一个AccountController中,使用UserManager和SignInManager为ReciptionBank(血库接收方)创建对应的注册和登录表单,请问该如何实现?
现有代码如下:
namespace BloodBank.Controllers { public class AccountController : Controller { private UserManager<Donor> _userManager; private SignInManager<Donor> _signInManager; public AccountController(UserManager<Donor> userManager, SignInManager<Donor> signInManager) { _userManager = userManager; _signInManager = signInManager; } [HttpGet] public IActionResult Register_Donor() { return View(); } [HttpPost] public async Task<IActionResult> Register_Donor(DonorRegisterViewModel model) { if (ModelState.IsValid) { Donor user = new Donor { FirstName = model.FirstName, LastName = model.LastName, UserName = model.UserName, PhoneNumber = model.PhonNum, NationalityNum = model.NationalityNum, Age = model.Age, GenderType = model.GenderType, TypeBlood = model.TypeBlood, Address = model.Address }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { return RedirectToAction("Login"); } foreach (var err in result.Errors) { ModelState.AddModelError("", err.Description); } return View(model); } return View(model); } [HttpGet] public IActionResult Login() { return View(); } [HttpPost] public async Task<IActionResult> Login(DonorLoginViewModel model) { if (ModelState.IsValid) { var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, false); if (result.Succeeded) { return RedirectToAction("DonorHome", "Donor"); } ModelState.AddModelError("", "Invalid User Or Password"); return View(model); } return View(model); } [HttpGet] public IActionResult Register_ReciptionBank() { return View(); } [HttpPost] public async Task<IActionResult> Register_ReciptionBank(ReciptionBank model) { if (ModelState.IsValid) { ReciptionBank bank = new ReciptionBank { HospitalName=model.HospitalName, Location=model.Location }; var result = await _userManager.CreateAsync(bank, model.HospitalName); } return View(model); } } }
解决方案步骤
1. 统一用户基类
确保Donor和ReciptionBank都继承自同一个Identity用户基类(比如IdentityUser或自定义AppUser),让UserManager和SignInManager能同时处理两种用户类型:
// 自定义通用用户基类(也可直接使用IdentityUser) public class AppUser : IdentityUser { // 可添加通用属性,如创建时间等 } // 献血者类继承基类 public class Donor : AppUser { public string FirstName { get; set; } public string LastName { get; set; } public string NationalityNum { get; set; } public int Age { get; set; } public string GenderType { get; set; } public string TypeBlood { get; set; } public string Address { get; set; } } // 血库接收方类继承基类 public class ReciptionBank : AppUser { public string HospitalName { get; set; } public string Location { get; set; } }
2. 修改Controller依赖注入
将原UserManager<Donor>和SignInManager<Donor>替换为针对基类的实例,支持两种用户处理:
private readonly UserManager<AppUser> _userManager; private readonly SignInManager<AppUser> _signInManager; public AccountController(UserManager<AppUser> userManager, SignInManager<AppUser> signInManager) { _userManager = userManager; _signInManager = signInManager; }
3. 完善ReciptionBank注册逻辑
3.1 创建注册ViewModel
避免直接用实体类接收请求,创建专用ViewModel:
public class ReciptionBankRegisterViewModel { [Required] public string HospitalName { get; set; } [Required] public string Location { get; set; } [Required] [Display(Name = "用户名")] public string UserName { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } [Required] [DataType(DataType.Password)] [Compare("Password", ErrorMessage = "密码与确认密码不匹配")] public string ConfirmPassword { get; set; } }
3.2 实现注册方法
修改原Register_ReciptionBank方法,完善业务逻辑:
[HttpGet] public IActionResult Register_ReciptionBank() { return View(); } [HttpPost] public async Task<IActionResult> Register_ReciptionBank(ReciptionBankRegisterViewModel model) { if (ModelState.IsValid) { var bank = new ReciptionBank { UserName = model.UserName, HospitalName = model.HospitalName, Location = model.Location }; var result = await _userManager.CreateAsync(bank, model.Password); if (result.Succeeded) { return RedirectToAction("Login"); } // 注册失败时添加错误提示 foreach (var err in result.Errors) { ModelState.AddModelError("", err.Description); } } return View(model); }
4. 实现ReciptionBank登录功能
4.1 创建通用登录ViewModel
支持用户类型选择,兼容两种身份登录:
public class LoginViewModel { [Required] public string UserName { get; set; } [Required] [DataType(DataType.Password)] public string Password { get; set; } [Display(Name = "记住我")] public bool RememberMe { get; set; } // 用户类型标识:Donor/ReciptionBank public string UserType { get; set; } }
4.2 修改登录方法
根据用户类型跳转对应页面:
[HttpGet] public IActionResult Login() { return View(); } [HttpPost] public async Task<IActionResult> Login(LoginViewModel model) { if (ModelState.IsValid) { var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, false); if (result.Succeeded) { var user = await _userManager.FindByNameAsync(model.UserName); // 根据用户类型跳转对应主页 if (user is Donor) { return RedirectToAction("DonorHome", "Donor"); } else if (user is ReciptionBank) { return RedirectToAction("BankHome", "ReciptionBank"); } } ModelState.AddModelError("", "用户名或密码错误"); } return View(model); }
5. 配置视图
- 为
Register_ReciptionBank创建视图,绑定ReciptionBankRegisterViewModel的字段; - 修改Login视图,添加
UserType的单选按钮或下拉选择框,让用户选择登录身份。
内容的提问来源于stack exchange,提问作者Basel Awadeen
相关产品推荐
相关产品推荐

