I'm learning Blazor and need some help.
My Blazor Server project requires an extended IdentityUser.
I would like to access the FirstName property in the LoginDisplay.razor file which is shown below.
Most of the discussions I have found are too old or do not address my specific issue.
MyProjectUser
using Microsoft.AspNetCore.Identity;
namespace MyProject.Data;
public class MyProjectUser : IdentityUser
{
[PersonalData]
public string? FirstName { get; set; }
[PersonalData]
public string? LastName { get; set; }
}
MyProjectContext
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace MyProject.Data;
public class MyProjectContext : IdentityDbContext<MyProjectUser>
{
public MyProjectContext(DbContextOptions<MyProjectContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
MyProject's Program.cs
using MyProject.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Components.Authorization;
using MyProject.Areas.Identity;
namespace MyProject
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("MyProjectContext") ?? throw new InvalidOperationException("Connection string 'MyProjectContext' not found.");
builder.Services.AddDbContext<MyProjectContext>(options => options.UseSqlServer(connectionString));
builder.Services.AddDefaultIdentity<MyProjectUser>(options => options.SignIn.RequireConfirmedAccount = true).AddEntityFrameworkStores<MyProjectContext>();
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<MyProjectUser>>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
}
}
}
Everything works great, database is updated etc.
I simply want to access the MyProjectUser's FirstName property here:
LoginDisplay.razor
<CascadingAuthenticationState>
<AuthorizeView>
<Authorized>
<a href="Identity/Account/Manage">Hello, -->@context.User.Identity?.Name!</a>
<form method="post" action="Identity/Account/Logout">
<button type="submit" class="nav-link btn btn-link">Log out</button>
</form>
</Authorized>
<NotAuthorized>
<a href="Identity/Account/Register">Register</a>
<a href="Identity/Account/Login">Log in</a>
</NotAuthorized>
</AuthorizeView>
</CascadingAuthenticationState>
The LoginDisplay is used in MainLayout.razor
@using Microsoft.AspNetCore.Identity;
@using MyProject.Data;
@inherits LayoutComponentBase
@inject UserManager<MyProjectUser> UserManager;
@inject AuthenticationStateProvider GetAuthenticationStateAsync
<PageTitle>MyProject</PageTitle>
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<LoginDisplay />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
Any help is greatly appreciated.
We need to add custom properities in MyProjectUser class, and run below command.
PM> Add-Migration FirstName -Context 'MyProjectContext'
PM> Update-Database -Context 'MyProjectContext'
Then I navigate to the Data in DB, add my FirstName and LastName.
My LoginDisplay.razor
@using blazorfirstname.Areas.Identity.Data
@using Microsoft.AspNetCore.Identity
@inject UserManager<MyProjectUser> userManager
@inject AuthenticationStateProvider authenticationStateProvider
<AuthorizeView>
<Authorized>
<a href="Identity/Account/Manage">Hello, @GetFirstNameAsync() !</a>
<form method="post" action="Identity/Account/Logout">
<button type="submit" class="nav-link btn btn-link">Log out</button>
</form>
</Authorized>
<NotAuthorized>
<a href="Identity/Account/Register">Register</a>
<a href="Identity/Account/Login">Log in</a>
</NotAuthorized>
</AuthorizeView>
@code {
private string firstName;
protected override async Task OnInitializedAsync()
{
var authenticationState = await authenticationStateProvider.GetAuthenticationStateAsync();
var user = await userManager.GetUserAsync(authenticationState.User);
firstName = user?.FirstName;
}
private string GetFirstNameAsync()
{
return firstName ?? string.Empty;
}
}
My MyProjectUser.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
namespace blazorfirstname.Areas.Identity.Data;
// Add profile data for application users by adding properties to the MyProjectUser class
public class MyProjectUser : IdentityUser
{
[PersonalData]
public string? FirstName { get; set; }
[PersonalData]
public string? LastName { get; set; }
}