Я создаю простую демонстрацию, которую вы можете выбрать UserType
при регистрации пользователя. И назначьте все связанные роли UserType
пользователю.
1.Модели:
public class ApplicationUser : IdentityUser
{
[ForeignKey("UserType")]
public int UserTypeId {get;set;}
public UserType UserType { get; set; }
}
public class UserType
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public List<ApplicationUser> Users { get; set; }
public List<ApplicationRole> Roles { get; set; }
}
public class ApplicationRole : IdentityRole
{
[ForeignKey("UserType")]
public int? UserTypeId {get;set;}
public UserType UserType { get; set; }
}
2.DbContext
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<UserType> UserTypes { get; set; }
public DbSet<ApplicationRole> AppRoles { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>()
.HasOne(c => c.UserType)
.WithMany(u=>u.Users)
.OnDelete(DeleteBehavior.Restrict);
}
}
3.Register.cs html .cs
public class InputModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
public int UserTypeId { get; set; }
}
public async Task OnGetAsync(string returnUrl = null)
{
ViewData["UserType"] = new SelectList(_context.UserTypes, "Id", "Name");
ReturnUrl = returnUrl;
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email, UserTypeId = Input.UserTypeId };
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
//add bunch of roles to user
var roles = _context.AppRoles.Where(r => r.UserTypeId == user.UserTypeId).Select(r => r.Name).ToList();
foreach(var role in roles)
{
await _userManager.AddToRoleAsync(user, role);
}
//...
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
4.Register.cs html
<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
<h4>Create a new account.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.ConfirmPassword"></label>
<input asp-for="Input.ConfirmPassword" class="form-control" />
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.UserTypeId"></label>
<select asp-for="Input.UserTypeId" asp-items="@ViewBag.UserType" class="form-control"></select>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
4.Startup.cs
services.AddDefaultIdentity<ApplicationUser>()
.AddRoles<ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();