Alıştırma - Identity’yi Özelleştirme
Identity, kullanıcıyı varsayılan olarak IdentityUser sınıfıyla temsil eder. Kayıt sırasında yakalanan verileri genişletmenin yollarından biri, IdentityUser sınıfından türetilen bir sınıf oluşturmaktır. Bu ünitede, ContosoPetsUser adlı bir türetilmiş sınıf oluşturulur. ContosoPetsUser, kullanıcının adını ve soyadını depolamaya yönelik özellikleri içerir.

Ek kullanıcı profili bilgilerini toplamak için kullanıcı arabiriminde değişiklik yapılması da gerekir. Aşağıdaki adımlar, kayıtlı kullanıcının ad ve soyadı bilgilerini toplama işlemini açıklar.
Kullanıcı hesabı verilerini özelleştirme
Değiştirilecek kullanıcı kaydı dosyalarını projeye ekleyin:
dotnet aspnet-codegenerator identity \ --dbContext ContosoPetsAuth \ --files "Account.Manage.EnableAuthenticator;Account.Manage.Index;Account.Register" \ --userClass ContosoPetsUser \ --forceYukarıdaki komutta:
--dbContextseçeneğiDbContextsınıfından türetilmişContosoPetsAuthsınıfına yönelik bilgileri araca sağlar.--filesseçeneği Identity alanına eklenecek benzersiz dosyaların noktalı virgülle ayrılmış listesini belirtir.--userClassseçeneği,IdentityUsersınıfından türetilmişContosoPetsUsersınıfının oluşturulmasıyla sonuçlanır.--forceseçeneği Identity alanında bulunan mevcut dosyaların üzerine yazılmasına neden olur.
İpucu
--filesseçeneğine yönelik geçerli değerleri görüntülemek için proje kökünde aşağıdaki komutu çalıştırın:dotnet aspnet-codegenerator identity --listFilesAşağıdaki dosyalar Areas/Identity dizinine eklenir:
- Data/
- ContosoPetsUser.cs
- Pages/
- _ViewImports.cshtml
- Account/
- _ViewImports.cshtml
- Register.cshtml
- Register.cshtml.cs
- Manage/
- _ManageNav.cshtml
- _ViewImports.cshtml
- EnableAuthenticator.cshtml
- EnableAuthenticator.cshtml.cs
- Index.cshtml
- Index.cshtml.cs
- ManageNavPages.cs
Buna ek olarak,
--forceseçeneği kullanıldığından yukarıdaki komut çalıştırılmadan önce mevcut olan Data/ContosoPetsAuth.cs dosyasının da üzerine yazılır.ContosoPetsAuthsınıf bildirimi şimdi yeni oluşturulanContosoPetsUserkullanıcı türüne başvurur:public class ContosoPetsAuth : IdentityDbContext<ContosoPetsUser>EnableAuthenticator Razor sayfası iskeleli hale getirildi. Ancak, bu sayfa modülün sonraki kısımlarına kadar değiştirilmeyecek.
Areas/Identity/IdentityHostingStartup.cs dosyasının
ConfiguremetodundaAddDefaultIdentityçağrısının yeni Identity kullanıcı türüyle ilgili bilgi sahibi olması gerekir. Aşağıda vurgulanan değişikliği ekleyip dosyayı kaydedin.services.AddDefaultIdentity<ContosoPetsUser>() .AddDefaultUI() .AddEntityFrameworkStores<ContosoPetsAuth>();Aşağıda vurgulanan değişiklikleri eklemek için Pages/Shared/_LoginPartial.cshtml dosyasını güncelleştirin. Yaptığınız değişiklikleri kaydedin.
@using Microsoft.AspNetCore.Identity @using ContosoPets.Ui.Areas.Identity.Data @inject SignInManager<ContosoPetsUser> SignInManager @inject UserManager<ContosoPetsUser> UserManager <ul class="navbar-nav">Yukarıdaki değişiklikler,
@injectyönergelerindeSignInManager<T>veUserManager<T>öğelerine geçirilen kullanıcı türünü güncelleştirir. VarsayılanIdentityUsertürünün yerine artıkContosoPetsUserkullanıcısına başvurulur.ContosoPetsUserbaşvurularını çözümlemek için@usingyönergesi eklendi.Pages/Shared/_LoginPartial.cshtml, fiziksel olarak Identity alanının dışında bulunur. Sonuç olarak, dosya iskele aracı tarafından otomatik olarak güncelleştirilmedi. Uygun değişikliklerin el ile yapılması gerekti.
İpucu
_LoginPartial.cshtml dosyasını el ile düzenlemeye alternatif olarak dosya, iskele aracı çalıştırılmadan önce silinebilir. _LoginPartial.cshtml dosyası, yeni
ContosoPetsUsersınıfına yönelik başvurular ile yeniden oluşturulur.Ek kullanıcı profili verilerinin alınmasını ve depolanmasını desteklemek için Areas/Identity/Data/ContosoPetsUser.cs dosyasını güncelleştirin. Aşağıdaki değişiklikleri yapın:
FirstNameveLastNameözelliklerini ekleyin:public class ContosoPetsUser : IdentityUser { [Required] [MaxLength(100)] public string FirstName { get; set; } [Required] [MaxLength(100)] public string LastName { get; set; } }Yukarıdaki kod parçacığındaki özellikler, temel alınan
AspNetUserstablosunda oluşturulacak ek sütunları temsil eder. Her iki özellik de gerekli olduğundan, bunlara[Required]özniteliğiyle not eklenir.[Required]özniteliği aynı zamanda, temel alınan veritabanı tablosu sütununda null olmama kısıtlamasıyla sonuçlanır. Ayrıca,[MaxLength]özniteliği maksimum uzunluk olarak 100 karaktere izin verildiğini belirtir. Temel alınan tablo sütununun veri türü de buna uygun olarak tanımlanır.Aşağıdaki
usingdeyimini dosyanın en üstüne ekleyin. Yaptığınız değişiklikleri kaydedin.using System.ComponentModel.DataAnnotations;Yukarıdaki kod,
FirstNameveLastNameözelliklerine uygulanan veri açıklaması özniteliklerini çözümler.
Veritabanını güncelleştirme
Temel alınan veri deposunu güncelleştirmek için EF Core geçişi oluşturma ve uygulama:
dotnet ef migrations add UpdateUser && \ dotnet ef database updateUpdateUserEF Core geçişi,AspNetUserstablosunun şemasına bir DDL değişiklik betiği uyguladı. Aşağıdaki geçiş çıkışı alıntısında görüldüğü gibi, özellikleFirstNameveLastNamesütunları eklendi:info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (1,005ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] ALTER TABLE "AspNetUsers" ADD "FirstName" character varying(100) NOT NULL DEFAULT ''; info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (517ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] ALTER TABLE "AspNetUsers" ADD "LastName" character varying(100) NOT NULL DEFAULT '';info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (37ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] ALTER TABLE [AspNetUsers] ADD [FirstName] nvarchar(100) NOT NULL DEFAULT N''; info: Microsoft.EntityFrameworkCore.Database.Command[20101] Executed DbCommand (36ms) [Parameters=[], CommandType='Text', CommandTimeout='30'] ALTER TABLE [AspNetUsers] ADD [LastName] nvarchar(100) NOT NULL DEFAULT N'';UpdateUserEF Core geçişi tarafındanAspNetUserstablosunun şemasına uygulanan etkileri analiz etmek için aşağıdaki adımları izleyin. Identity veri modelini genişletmenin, temel alınan veri deposu üzerindeki etkilerine yönelik bilgi edinirsiniz.
Tablo şemasını görüntülemek için aşağıdaki komutu çalıştırın:
db -c '\d "AspNetUsers"'Aşağıdaki çıkış görüntülenir:
Table "public.AspNetUsers" Column | Type | Collation | Nullable | Default ----------------------+--------------------------+-----------+----------+----------------------- Id | text | | not null | UserName | character varying(256) | | | NormalizedUserName | character varying(256) | | | Email | character varying(256) | | | NormalizedEmail | character varying(256) | | | EmailConfirmed | boolean | | not null | PasswordHash | text | | | SecurityStamp | text | | | ConcurrencyStamp | text | | | PhoneNumber | text | | | PhoneNumberConfirmed | boolean | | not null | TwoFactorEnabled | boolean | | not null | LockoutEnd | timestamp with time zone | | | LockoutEnabled | boolean | | not null | AccessFailedCount | integer | | not null | FirstName | character varying(100) | | not null | ''::character varying LastName | character varying(100) | | not null | ''::character varyingContosoPetsUsersınıfındakiFirstNameveLastNameözellikleri, yukarıdaki çıkışta bulunanFirstNameveLastNamesütunlarına karşılık gelir.[MaxLength(100)]öznitelikleri nedeniyle her iki sütuna dacharacter varying(100)veri türü atandı.[Required]öznitelikleri nedeniyle null olmama kısıtlaması eklendi.Komut kabuğunda, aşağıdaki dizin bilgileri görüntülenene kadar aşağı kaydırın:
Indexes: "PK_AspNetUsers" PRIMARY KEY, btree ("Id") "UserNameIndex" UNIQUE, btree ("NormalizedUserName") "EmailIndex" btree ("NormalizedEmail")PK_AspNetUsersdizini,Idsütununun bir kullanıcı hesabına yönelik benzersiz tanıtıcı olduğunu gösterir.Komut kabuğundaki metin görüntüleyicisinden çıkmak için q tuşuna basın.
Tablo şemasını görüntülemek için aşağıdaki komutu çalıştırın:
db -Q "SELECT COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH AS MAX_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='AspNetUsers'" -Y 20Aşağıdaki çıkış görüntülenir:
COLUMN_NAME IS_NULLABLE DATA_TYPE MAX_LENGTH -------------------- ----------- -------------------- ----------- Id NO nvarchar 450 UserName YES nvarchar 256 NormalizedUserName YES nvarchar 256 Email YES nvarchar 256 NormalizedEmail YES nvarchar 256 EmailConfirmed NO bit NULL PasswordHash YES nvarchar -1 SecurityStamp YES nvarchar -1 ConcurrencyStamp YES nvarchar -1 PhoneNumber YES nvarchar -1 PhoneNumberConfirmed NO bit NULL TwoFactorEnabled NO bit NULL LockoutEnd YES datetimeoffset NULL LockoutEnabled NO bit NULL AccessFailedCount NO int NULL FirstName NO nvarchar 100 LastName NO nvarchar 100ContosoPetsUsersınıfındakiFirstNameveLastNameözellikleri, yukarıdaki çıkışta bulunanFirstNameveLastNamesütunlarına karşılık gelir.[MaxLength(100)]öznitelikleri nedeniyle her iki sütuna danvarchar(100)veri türü atandı.[Required]öznitelikleri nedeniyle null olmama kısıtlaması eklendi. Mevcut satırlar, yeni sütunlarda boş dizeler gösterir.Tablonun birincil anahtarını görüntülemek için aşağıdaki komutu çalıştırın:
db -i $setupWorkingDirectory/list-aspnetusers-pk.sql -Y 15Aşağıdaki çıkış,
Idsütununun bir kullanıcı hesabı için benzersiz tanıtıcı olduğunu gösterir:Table Column Primary key --------------- --------------- --------------- AspNetUsers Id PK_AspNetUsers
Kullanıcı kaydı formunu özelleştirme
Areas/Identity/Pages/Account/Register.cshtml dosyasına aşağıda vurgulanmış işaretlemeyi ekleyin:
<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.FirstName"></label> <input asp-for="Input.FirstName" class="form-control" /> <span asp-validation-for="Input.FirstName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Input.LastName"></label> <input asp-for="Input.LastName" class="form-control" /> <span asp-validation-for="Input.LastName" class="text-danger"></span> </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>Yukarıdaki işaretleme ile, Ad ve Soyadı metin kutuları kullanıcı kaydı formuna eklenir.
Areas/Identity/Pages/Account/Register.cshtml.cs dosyasına ad metin kutuları için destek ekleyin.
İç içe geçmiş
InputModelsınıfınaFirstNameveLastNameözelliklerini ekleyin:public class InputModel { [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 1)] [Display(Name = "First name")] public string FirstName { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 1)] [Display(Name = "Last name")] public string LastName { get; set; } [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; } }[Display]öznitelikleri, metin kutularıyla ilişkilendirilecek etiket metnini tanımlar.ContosoPetsUsernesnesindeFirstNameveLastNameözelliklerini ayarlamak içinOnPostAsyncmetodunu değiştirin. Aşağıda vurgulanan değişiklikleri yapın:public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { var user = new ContosoPetsUser { FirstName = Input.FirstName, LastName = Input.LastName, UserName = Input.Email, Email = Input.Email, }; var result = await _userManager.CreateAsync(user, Input.Password); if (result.Succeeded) {Yukarıdaki değişiklik,
FirstNameveLastNameözelliklerini kayıt formundaki kullanıcı girişine ayarlar.
Site üst bilgisini özelleştirme
Kullanıcı kaydı sırasında toplanan ad ve soyadı bilgilerini görüntülemek için Pages/Shared/_LoginPartial.cshtml dosyasını güncelleştirin. Aşağıdaki kod parçacığında vurgulanan satırlar gereklidir:
@using Microsoft.AspNetCore.Identity
@using ContosoPets.Ui.Areas.Identity.Data
@inject SignInManager<ContosoPetsUser> SignInManager
@inject UserManager<ContosoPetsUser> UserManager
<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
ContosoPetsUser user = await UserManager.GetUserAsync(User);
var fullName = $"{user.FirstName} {user.LastName}";
<li class="nav-item">
<a id="manage" class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello, @fullName!</a>
</li>
<li class="nav-item">
<form id="logoutForm" class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/Index", new { area = "" })">
<button id="logout" type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" id="register" asp-area="Identity" asp-page="/Account/Register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" id="login" asp-area="Identity" asp-page="/Account/Login">Login</a>
</li>
}
</ul>
Profil yönetimi formunu özelleştirme
Areas/Identity/Pages/Account/Manage/Index.cshtml dosyasına aşağıda vurgulanmış işaretlemeyi ekleyin. Yaptığınız değişiklikleri kaydedin.
<form id="profile-form" method="post"> <div asp-validation-summary="All" class="text-danger"></div> <div class="form-group"> <label asp-for="Input.FirstName"></label> <input asp-for="Input.FirstName" class="form-control" /> <span asp-validation-for="Input.FirstName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Input.LastName"></label> <input asp-for="Input.LastName" class="form-control" /> <span asp-validation-for="Input.LastName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Username"></label> <input asp-for="Username" class="form-control" disabled /> </div>Ad metin kutularına yönelik desteği sunmak için Areas/Identity/Pages/Account/Manage/Index.cshtml.cs dosyasında aşağıdaki değişiklikleri yapın.
İç içe geçmiş
InputModelsınıfınaFirstNameveLastNameözelliklerini ekleyin:public class InputModel { [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 1)] [Display(Name = "First name")] public string FirstName { get; set; } [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 1)] [Display(Name = "Last name")] public string LastName { get; set; } [Phone] [Display(Name = "Phone number")] public string PhoneNumber { get; set; } }LoadAsyncmetodunda vurgulanan değişiklikleri ekleyin:private async Task LoadAsync(ContosoPetsUser user) { var userName = await _userManager.GetUserNameAsync(user); var phoneNumber = await _userManager.GetPhoneNumberAsync(user); Username = userName; Input = new InputModel { PhoneNumber = phoneNumber, FirstName = user.FirstName, LastName = user.LastName, }; }Yukarıdaki kod, profil yönetimi formunun karşılık gelen metin kutularında görüntülenmesi için ad ve soyadı bilgilerinin alınmasına yönelik destek sunar.
Vurgulanan değişiklikleri
OnPostAsyncmetoduna ekleyin. Yaptığınız değişiklikleri kaydedin.public async Task<IActionResult> OnPostAsync() { var user = await _userManager.GetUserAsync(User); if (user == null) { return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); } if (!ModelState.IsValid) { await LoadAsync(user); return Page(); } user.FirstName = Input.FirstName; user.LastName = Input.LastName; await _userManager.UpdateAsync(user); var phoneNumber = await _userManager.GetPhoneNumberAsync(user); if (Input.PhoneNumber != phoneNumber) { var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber); if (!setPhoneResult.Succeeded) { var userId = await _userManager.GetUserIdAsync(user); throw new InvalidOperationException($"Unexpected error occurred setting phone number for user with ID '{userId}'."); } } await _signInManager.RefreshSignInAsync(user); StatusMessage = "Your profile has been updated"; return RedirectToPage(); }Yukarıdaki kod, veritabanının
AspNetUserstablosunda yer alan ad ve soyadı bilgilerinin güncelleştirilmesine yönelik destek sunar.
Derleme, dağıtma ve test etme
Uygulamayı derlemek için aşağıdaki komutu çalıştırın:
dotnet build --no-restoreSon derlemeden sonra NuGet paketi eklenmediğinden
--no-restoreseçeneği de eklenmiştir. Derleme işlemi, NuGet paketlerinin geri yüklenmesini atlar ve uyarı oluşturmadan başarıyla tamamlanır. Derleme başarısız olursa, sorun giderme bilgileri için çıkışı inceleyin.Aşağıdaki komutu çalıştırarak uygulamayı Azure App Service’e dağıtın:
az webapp upTarayıcınızda uygulamaya gidin. Oturumunuz hala açıksa Oturumu kapat seçeneğini belirleyin.
İpucu
Uygulamanıza yönelik URL’ye ihtiyacınız varsa, aşağıdaki komut ile bunu görüntüleyin:
echo $webAppUrlYeni bir kullanıcı kaydetmek için Kaydolun’u seçip güncelleştirilmiş formu kullanın.
Not
Ad ve Soyadı alanlarındaki doğrulama kısıtlamaları,
InputModelsınıfınıFirstNameveLastNameözelliklerindeki veri açıklamalarını yansıtır.Kaydolduktan sonra giriş sayfasına yönlendirilirsiniz. Uygulamanın üst bilgisi artık şunu içerir: Merhaba [Ad] [Soyadı]!.
Ad ve soyadlarının veritabanında depolandığını doğrulamak için aşağıdaki komutu çalıştırın:
db -c 'SELECT "UserName", "Email", "FirstName", "LastName" FROM "AspNetUsers"'Aşağıdaki çıkışın bir varyasyonu görüntülenir:
UserName | Email | FirstName | LastName ---------------------------+---------------------------+-----------+---------- kai.klein@contoso.com | kai.klein@contoso.com | | jana.heinrich@contoso.com | jana.heinrich@contoso.com | Jana | Heinrich (2 rows)db -Q "SELECT UserName, Email, FirstName, LastName FROM dbo.AspNetUsers" -Y 25Aşağıdaki çıkışın bir varyasyonu görüntülenir:
UserName Email FirstName LastName ------------------------- ------------------------- ------------------------- ------------------------- kai.klein@contoso.com kai.klein@contoso.com jana.heinrich@contoso.com jana.heinrich@contoso.com Jana HeinrichFirstNameveLastNameöğelerini şemaya eklemeden önce kaydolan ilk kullanıcı. Sonuç olarak, ilişkiliAspNetUserstablo kaydının bu sütunlarda verileri yoktur.
Profil yönetimi formundaki değişiklikleri test etme
Oluşturduğunuz ilk kullanıcıyla web uygulamasında oturum açın.
Merhaba ! bağlantısına tıklayıp profil yönetimi formuna gidin.
Not
AspNetUserstablosunun bu kullanıcıya yönelik satırıFirstNameveLastNamedeğerlerini içermediğinden bağlantı düzgün şekilde görüntülenmez.Ad ve Soyadı için geçerli değerleri girin. Kaydet’i seçin.
Uygulamanın üst bilgisi şöyle güncelleştirilir: Merhaba, [Ad] [Soyadı]!.
Yardıma mı ihtiyacınız var? Sorun giderme kılavuzumuza gözatın veya sorun bildirerek belirli bir konuda geri bildiriminizi paylaşın.