ASP NET CORE RAZOR PAGE BAKIM TEKNİK SERVİS PROJESİ DERS 016 ROLLERİN TANIMLANMASI

Projemizde en başta iki tipte rol olacağnı belirtmiştim. Bunlardan birisi yönetici konumunda olan Admin, diğeri ise müşteri rolünde olan standart kullanıcı yani user. Dolayısı ile benim aslınd bu iki rolü database tarafında oluşturmam lazım. Bunu yapabilmek için ben ana dizine Utility adında bir klasör oluşturuyorum ve tüm rollerimi burada bir sınıf oluşturup içine alacağım. Utility klasörünün içine bir class ekliyor ve adını StatikRoller verdim. Buraya şimdi iki tane sabit tipte string değişken ekleyeceğim.

Dersin video versiyonunu aşağıdan izleyebilirsiniz.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GursoyCNCBakim.Utility
{
    public static class StatikRoller
    {
        public const string AdminKullanici = "Admin";
        public const string MusteriKullanici = "Musteri";
    }
}

Şimdi yavaş yavaş değişikliklere başlama zamanı geldi. Register.cshtml.cs içine geliyorum. Artık IdentityUser yerine benim uygulamama özel olan ApplicationUser kullanmam lazım. Değişikliğimi yapıyorum.

ApplicationUser içindeki tüm özelliklerin de burada atama işlemini gerçekleştirdim. Şimdi benim ilk kullanıcım Admin rolünde olacak.

Kodlarımızı yazalım.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using GursoyCNCBakim.Data;
using GursoyCNCBakim.Models;
using GursoyCNCBakim.Utility;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;

namespace GursoyCNCBakim.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class RegisterModel : PageModel
    {
        private readonly SignInManager< IdentityUser > _signInManager;
        private readonly UserManager< IdentityUser > _userManager;
        private readonly ILogger< RegisterModel > _logger;
        private readonly IEmailSender _emailSender;
        private readonly RoleManager< IdentityRole > _roleManager;
        private readonly ApplicationDbContext _db;

        public RegisterModel(
            UserManager< IdentityUser > userManager,
            SignInManager< IdentityUser > signInManager,
            ILogger< RegisterModel > logger,
            IEmailSender emailSender,
            RoleManager< IdentityRole > roleManager,
            ApplicationDbContext db)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _logger = logger;
            _emailSender = emailSender;
            _db = db;
            _roleManager = roleManager;
        }

        [BindProperty]
        public InputModel Input { get; set; }

        public string ReturnUrl { get; set; }

        public IList< AuthenticationScheme > ExternalLogins { get; set; }

        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; }

            [Required]
            public string AdSoyad { get; set; }
            public string Adres { get; set; }
            public string Sehir { get; set; }
            public string PostaKodu { get; set; }

            [Required]
            public string PhoneNumber { get; set; }

        }

        public async Task OnGetAsync(string returnUrl = null)
        {
            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,
                    AdSoyad = Input.AdSoyad,
                    Adres = Input.Adres,
                    Sehir = Input.Sehir,
                    PostaKodu = Input.PostaKodu,
                    PhoneNumber = Input.PhoneNumber
                };
                var result = await _userManager.CreateAsync(user, Input.Password);
                if (result.Succeeded)
                {
                    if (!await _roleManager.RoleExistsAsync(StatikRoller.AdminKullanici))
                    {
                        await _roleManager.CreateAsync(new IdentityRole(StatikRoller.AdminKullanici));
                    }

                    if (!await _roleManager.RoleExistsAsync(StatikRoller.MusteriKullanici))
                    {
                        await _roleManager.CreateAsync(new IdentityRole(StatikRoller.MusteriKullanici));
                    }

                    //!!!
                    await _userManager.AddToRoleAsync(user, StatikRoller.AdminKullanici);

                    _logger.LogInformation("User created a new account with password.");

                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                    code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
                    var callbackUrl = Url.Page(
                        "/Account/ConfirmEmail",
                        pageHandler: null,
                        values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
                        protocol: Request.Scheme);

                    await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                        $"Please confirm your account by clicking here.");

                    if (_userManager.Options.SignIn.RequireConfirmedAccount)
                    {
                        return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
                    }
                    else
                    {
                        await _signInManager.SignInAsync(user, isPersistent: false);
                        return LocalRedirect(returnUrl);
                    }
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }

            // If we got this far, something failed, redisplay form
            return Page();
        }
    }
}


Rolleri ekleyebilmek için dependency injection kullanarak role manageri kullandım.  ApplicationDbConretxt classımdan object türettim. Constructor içinde atama işlemlerii yaptım. Daha sonra post handler metoduma geliyorum ve kullanıcı oluşturma işleminin yapıldığı kod bloğundan sonra; rollerin veri tabanında olup olmadığını kontrol ediyorum. Daha sonra ilgili if şartına göre Admin veya müşteri tipinde rollerin eklenebilmesi için ilgili if bloklarımı yazıyorum. Burası çalışınca ilgili duruma göre admin veya müşteri rolü eklenecek. Buna ilişkin user manager üzerinden metodu çalıştırma kodunu da yazalım.

Şimdi projeyi çalıştıralım.

Biz bir hata aldık. Buradaki problem nedir?

Bu hatanın sebebi aslında bizim eklediğimiz RoleManager kaynaklı. Bunu ekledikten sonra benim startup.cs üzerinde configureservice alanına gelip, düzenlemem yapmam lazım. Benim burada DefaultIdentity tanımlı ancak bunun içinde RoleManager yer almıyor dolayısı ile değiştiriyorum.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using GursoyCNCBakim.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace GursoyCNCBakim
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure< CookiePolicyOptions >(options =>
           {
               options.CheckConsentNeeded = context => true;
               options.MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.None;
           });

            services.AddDbContext< ApplicationDbContext >(options =>
                options.UseSqlServer(
                    Configuration.GetConnectionString("DefaultConnection")));

            services.AddIdentity< IdentityUser, IdentityRole >().AddDefaultTokenProviders().AddDefaultUI().AddEntityFrameworkStores< ApplicationDbContext >();
                


            services.AddRazorPages().AddRazorRuntimeCompilation();

            services.AddDbContext< ApplicationDbContext >(options =>
                    options.UseSqlServer(Configuration.GetConnectionString("GursoyCNCBakimContext")));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                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.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapRazorPages();
            });
        }
    }
}

Böylelikle artık yapılandırma ayarlarım da tam. Şimdi kayıt olalım.

Kayıt işlemim de gerçekleşti görünüyor, database tarafına geçip tablomıza bakalım.

Tablolarımızda kullanıcı rollerimiz tanımlı.

MÜŞTERİ ROLÜ İLE KAYIT İŞLEMİNİN YAPILMASI

İlk kullanıcımızı admin olarak kaydettik. Bundan sonra kayıt olan kullanıcıların ben Müşteri olarak kaydolmasını istiyorum, tabi ben daha önce ne yaptım ilk kaydı almak için Admin olarak kaydedebileğine dair kodlarımı yazdım o halde ben Register.cshtml.cs dosyama geliyor ve kodlarımı değiştiriyorum. Bundan sonra normal şekilde her kayıt Müşteri rolünde olsun istiyorum.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using GursoyCNCBakim.Data;
using GursoyCNCBakim.Models;
using GursoyCNCBakim.Utility;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;

namespace GursoyCNCBakim.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class RegisterModel : PageModel
    {
        private readonly SignInManager< IdentityUser > _signInManager;
        private readonly UserManager< IdentityUser > _userManager;
        private readonly ILogger< RegisterModel > _logger;
        private readonly IEmailSender _emailSender;
        private readonly RoleManager< IdentityRole > _roleManager;
        private readonly ApplicationDbContext _db;

        public RegisterModel(
            UserManager< IdentityUser > userManager,
            SignInManager< IdentityUser > signInManager,
            ILogger< RegisterModel > logger,
            IEmailSender emailSender,
            RoleManager< IdentityRole > roleManager,
            ApplicationDbContext db)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _logger = logger;
            _emailSender = emailSender;
            _db = db;
            _roleManager = roleManager;
        }

        [BindProperty]
        public InputModel Input { get; set; }

        public string ReturnUrl { get; set; }

        public IList< AuthenticationScheme > ExternalLogins { get; set; }

        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; }

            [Required]
            public string AdSoyad { get; set; }
            public string Adres { get; set; }
            public string Sehir { get; set; }
            public string PostaKodu { get; set; }

            [Required]
            public string PhoneNumber { get; set; }

        }

        public async Task OnGetAsync(string returnUrl = null)
        {
            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,
                    AdSoyad = Input.AdSoyad,
                    Adres = Input.Adres,
                    Sehir = Input.Sehir,
                    PostaKodu = Input.PostaKodu,
                    PhoneNumber = Input.PhoneNumber
                };
                var result = await _userManager.CreateAsync(user, Input.Password);
                if (result.Succeeded)
                {
                    if (!await _roleManager.RoleExistsAsync(StatikRoller.AdminKullanici))
                    {
                        await _roleManager.CreateAsync(new IdentityRole(StatikRoller.AdminKullanici));
                    }

                    if (!await _roleManager.RoleExistsAsync(StatikRoller.MusteriKullanici))
                    {
                        await _roleManager.CreateAsync(new IdentityRole(StatikRoller.MusteriKullanici));
                    }

                    //!!!
                    await _userManager.AddToRoleAsync(user, StatikRoller.MusteriKullanici);

                    _logger.LogInformation("User created a new account with password.");

                    var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
                    code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
                    var callbackUrl = Url.Page(
                        "/Account/ConfirmEmail",
                        pageHandler: null,
                        values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
                        protocol: Request.Scheme);

                    await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                        $"Please confirm your account by clicking here.");

                    if (_userManager.Options.SignIn.RequireConfirmedAccount)
                    {
                        return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
                    }
                    else
                    {
                        await _signInManager.SignInAsync(user, isPersistent: false);
                        return LocalRedirect(returnUrl);
                    }
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }

            // If we got this far, something failed, redisplay form
            return Page();
        }
    }
}

Database tarafına baktığımda her iki rolde de kullanıcı kayıtlı, herhangi bir sorun yok. Bir sonraki derste görüşmek üzere.

Dersin video versiyonunda daha detaya ulaşabilirsiniz. Görüşmek üzere.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir