In this tutorial, I will demo how to add more data fields to the standard users & roles database. In order to proceed with this tutorial, you need to have the following prerequisites:
- VS Code
- You have installed .NET 8.0
- You have installed the dotnet-ef tool
- You have installed the dotnet-aspnet-codegenerator tool
Companion Video: https://youtu.be/xo4usBberVA
Getting Started
Download the source code for an application that seeds some sample users and roles into an SQLite database from this GitHub repo:
git clone https://github.com/medhatelmasry/Code1stUsersRoles
cd Code1stUsersRoles
When you run this app, you will be able to access the privacy page (/privacy) with the following credentials:
Password | Role | Page | |
---|---|---|---|
aa@aa.aa | P@$$w0rd | Admin | /privacy |
mm@mm.mm | P@$$w0rd | Member | / |
This is because the PrivacyModel class in Pages/Privacy.cshtml.cs is annotated with the following:
[Authorize (Roles = "Member, Admin")]
Click on the Register link on the top-right side of your keyboard to add a new user.
Click on Logout in the top-right corner.
public class CustomUser : IdentityUser {public CustomUser() : base() { }public string? FirstName { get; set; }public string? LastName { get; set; }}
DescriptionCreatedDate
public class CustomRole : IdentityRole {public CustomRole() : base() { }public CustomRole(string roleName) : base(roleName) { }public CustomRole(string roleName, string description,DateTime createdDate): base(roleName) {base.Name = roleName;this.Description = description;this.CreatedDate = createdDate;}public string? Description { get; set; }public DateTime CreatedDate { get; set; }}
- When creating a role, add data for Description and CreatedDate.
- When creating a user, add data for FirstName & LastName.
builder.Services.AddIdentity<CustomUser, CustomRole>(options => {options.Stores.MaxLengthForKeys = 128;}).AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultUI().AddDefaultTokenProviders().AddRoles<CustomRole>();
@inject SignInManager<IdentityUser> SignInManager@inject UserManager<IdentityUser> UserManager
@inject SignInManager<CustomUser> SignInManager@inject UserManager<CustomUser> UserManager
dotnet ef migrations add M1 -o Data/Migrationsdotnet ef database update
Email: aa@aa.aa Password: P@$$w0rdEmail: mm@mm.mm Password: P@$$w0rd
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Designdotnet add package Microsoft.EntityFrameworkCore.Designdotnet add package Microsoft.EntityFrameworkCore.SqlServer
Visit the following site for more information on scaffolding identity views:
https://docs.microsoft.com/en-us/aspnet/core/security/authentication/scaffold-identity?view=aspnetcore-3.0&tabs=netcore-cli
Help with the tool | dotnet aspnet-codegenerator identity -h |
List all the views that can be scaffolded | dotnet aspnet-codegenerator identity --listFiles |
Scaffold three views | dotnet aspnet-codegenerator identity --files "Account.Register;Account.Login;Account.RegisterConfirmation" |
Expose all files | dotnet aspnet-codegenerator identity |
Since we need to modify the registration controller and view, we instruct the scaffolder to surface the code used for registration. To do this, we will scaffold three pages that pertain to account registration and login. Run the following command from within a terminal window:
[Required][DataType(DataType.Text)][StringLength(50, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 2)][Display(Name ="First Name")]public string FirstName { get; set; }[Required][DataType(DataType.Text)][StringLength(50, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 2)][Display(Name = "Last Name")]public string LastName { get; set; }
var user = new CustomUser {UserName = Input.Email,Email = Input.Email,FirstName = Input.FirstName,LastName = Input.LastName};
<div class="form-floating mb-3"><input asp-for="Input.FirstName" class="form-control" autocomplete="firstname" aria-required="true" placeholder="First Name"/><label asp-for="Input.FirstName"></label><span asp-validation-for="Input.FirstName" class="text-danger"></span></div><div class="form-floating mb-3"><input asp-for="Input.LastName" class="form-control" autocomplete="lastname" aria-required="true" placeholder="Last Name"/><label asp-for="Input.LastName"></label><span asp-validation-for="Input.LastName" class="text-danger"></span></div>