Test_Store => Application => Services => Users => Commands => UserLogin => IUserLoginService.cs
بیایید کد UserLoginService را بررسی کنیم. این کد به منظور احراز هویت کاربران و ورود آنها به سیستم طراحی شده است و شامل اینترفیس، کلاس سرویس، و یک DTO میشود.
توضیحات کد:
Interface IUserLoginService:
این اینترفیس یک متد Execute را تعریف میکند که نام کاربری (Username) و رمز عبور (Password) را میپذیرد و نتیجه عملیات را برمیگرداند. این متد یک شیء ResultDto<ResultUserloginDto> به عنوان خروجی برمیگرداند.
Class UserLoginService:
کلاس UserLoginService پیادهسازی اینترفیس IUserLoginService است.
Constructor:
سازنده کلاس که یک شیء از نوع IDataBaseContext دریافت میکند. این شیء برای دسترسی به دیتابیس استفاده میشود.
Method Execute:
این متد مسئول اجرای عملیات احراز هویت و ورود کاربر است.
ابتدا بررسی میکند که آیا فیلدهای Username و Password خالی یا نادرست هستند و در صورت لزوم پیام خطا برمیگرداند.
سپس کاربر را با استفاده از Username از دیتابیس پیدا میکند.
اگر کاربر یافت نشد، یک پیام خطا برمیگرداند.
اگر کاربر یافت شد، رمز عبور ورودی را با رمز عبور ذخیره شده مقایسه میکند.
اگر رمز عبور نادرست باشد، یک پیام خطا برمیگرداند.
اگر رمز عبور صحیح باشد، نقشهای کاربر را به صورت رشتهای (Roles) در ResultUserloginDto ذخیره میکند و نتیجه موفقیتآمیز بودن عملیات را برمیگرداند.
DTO Classes:
ResultUserloginDto:
این کلاس نمایشی از نتیجه احراز هویت کاربر شامل UserId, Roles, و Name است.
نحوه عملکرد Execute Method:
بررسی فیلدهای ورودی:
ابتدا بررسی میکند که آیا فیلدهای Username و Password خالی هستند یا خیر. اگر هر یک از فیلدها خالی باشد، یک پیام خطا شامل IsSuccess برابر با false و Message مناسب برمیگرداند.
پیدا کردن کاربر:
سپس کاربر را با استفاده از Username از دیتابیس پیدا میکند. اگر کاربر یافت نشد، یک پیام خطا شامل IsSuccess برابر با false و Message با مقدار "کاربری با این ایمیل در سایت فروشگاه باگتو ثبت نام نکرده است" برمیگرداند.
تأیید رمز عبور:
رمز عبور ورودی را با رمز عبور ذخیره شده مقایسه میکند. اگر رمز عبور نادرست باشد، یک پیام خطا شامل IsSuccess برابر با false و Message با مقدار "رمز وارد شده اشتباه است!" برمیگرداند.
ذخیره نقشها و بازگرداندن نتیجه:
نقشهای کاربر را به صورت رشتهای (Roles) در ResultUserloginDto ذخیره میکند.
نتیجه موفقیتآمیز بودن عملیات را با UserId, Roles, و Name کاربر برمیگرداند.
نتیجهگیری:
این کد به شما امکان میدهد تا کاربران را احراز هویت کنید و نتیجه عملیات ورود را به صورت یک شیء ResultDto شامل وضعیت موفقیت و پیام مناسب برگردانید. همچنین نقشهای کاربر را به صورت رشتهای در ResultUserloginDto ذخیره میکند.
Test_Store => Application => Services => Users => Commands => UserSatusChange => IUserSatusChangeService.cs
بیایید کد UserSatusChangeService را بررسی کنیم. این کد به منظور تغییر وضعیت فعالیت کاربران طراحی شده است و شامل اینترفیس، کلاس سرویس، و یک متد اصلی است.
توضیحات کد:
Namespace:
namespace Test_Store.Application.Services.Users.Commands.UserSatusChange:
نامفضا برای سازماندهی کدهای مرتبط با عملیات تغییر وضعیت کاربر.
Interface IUserSatusChangeService:
این اینترفیس یک متد Execute را تعریف میکند که شناسه کاربر (UserId) را میپذیرد و نتیجه عملیات را برمیگرداند. این متد یک شیء ResultDto به عنوان خروجی برمیگرداند.
Class UserSatusChangeService:
کلاس UserSatusChangeService پیادهسازی اینترفیس IUserSatusChangeService است.
Constructor:
سازنده کلاس که یک شیء از نوع IDataBaseContext دریافت میکند. این شیء برای دسترسی به دیتابیس استفاده میشود.
Method Execute:
این متد مسئول اجرای عملیات تغییر وضعیت کاربر است.
متد Execute:
این متد یک پارامتر UserId از نوع long میپذیرد که شناسه کاربری است که باید وضعیت آن تغییر کند.
ابتدا با استفاده از UserId کاربر مورد نظر را از دیتابیس پیدا میکند.
اگر کاربر یافت نشد، یک پیام خطا شامل IsSuccess برابر با false و Message با مقدار "کاربر یافت نشد" برمیگرداند.
اگر کاربر یافت شد، وضعیت فعالیت کاربر (IsActive) را به مقدار مخالف فعلی تغییر میدهد.
تغییرات را در دیتابیس ذخیره میکند.
وضعیت جدید کاربر را بررسی کرده و بر اساس آن پیام مناسب را تنظیم میکند.
در نهایت، یک پیام موفقیتآمیز شامل IsSuccess برابر با true و Message مناسب برمیگرداند.
نتیجهگیری:
این کد به شما امکان میدهد تا وضعیت فعالیت کاربران را به راحتی تغییر دهید و نتیجه عملیات را به صورت یک شیء ResultDto شامل وضعیت موفقیت و پیام مناسب برگردانید.
Test_Store => Domain => Entities => Commons => BaseEntity.cs
بیایید کد BaseEntity را بررسی کنیم. این کد شامل دو کلاس انتزاعی است که به عنوان پایه برای دیگر کلاسهای موجودیتها در پروژه شما عمل میکنند.
توضیحات کد:
Namespace:
namespace Test_Store.Domain.Entities.Commons:
نامفضا برای سازماندهی کدهای مرتبط با کلاسهای پایه و عمومی.
Abstract Class BaseEntity<TKey>:
این کلاس انتزاعی به منظور تعریف ویژگیهای عمومی موجودیتها ایجاد شده است و از نوع جنریک TKey استفاده میکند.
Properties:
public TKey Id { get; set; }:
شناسه موجودیت از نوع جنریک TKey.
public DateTime InsertTime { get; set; } = DateTime.Now;:
زمان درج موجودیت، به طور پیشفرض زمان فعلی را تنظیم میکند.
public DateTime? UpdateTime { get; set; }:
زمان بهروزرسانی موجودیت، مقدار نالپذیر.
public bool IsRemoved { get; set; } = false;:
وضعیت حذف موجودیت، به طور پیشفرض مقدار false دارد.
public DateTime? RemoveTime { get; set; }:
زمان حذف موجودیت، مقدار نالپذیر.
Abstract Class BaseEntity:
این کلاس انتزاعی از BaseEntity<long> ارثبری میکند و به عنوان یک کلاس پایه عمومی با شناسه از نوع long عمل میکند.
Inheritance:
public abstract class BaseEntity :
BaseEntity<long>: ارثبری از کلاس جنریک BaseEntity با نوع long برای شناسه.
نتیجهگیری:
این کد به شما امکان میدهد تا کلاسهای موجودیتهای مختلف را به سادگی و با استفاده از کلاس پایه BaseEntity ایجاد کنید. کلاس BaseEntity ویژگیهای عمومی مانند شناسه، زمان درج، زمان بهروزرسانی، وضعیت حذف، و زمان حذف را تعریف میکند که میتواند در تمامی موجودیتها استفاده شود. این ساختار به شما کمک میکند تا کدهای خود را سازماندهی کرده و تکرار کدها را کاهش دهید.
Test_Store => Domain => Entities => Commons => BaseEntityNotId.cs
بیایید کد BaseEntityNotId را بررسی کنیم. این کد شامل یک کلاس انتزاعی (abstract class) است که برای تعریف ویژگیهای عمومی موجودیتها در پروژه شما استفاده میشود.
توضیحات کد:
Namespace:
namespace Test_Store.Domain.Entities.Commons:
نامفضا برای سازماندهی کدهای مرتبط با کلاسهای پایه و عمومی.
Abstract Class BaseEntityNotId:
این کلاس انتزاعی به منظور تعریف ویژگیهای عمومی موجودیتها بدون شناسه (Id) ایجاد شده است.
Properties:
public DateTime InsertTime { get; set; } = DateTime.Now;:
زمان درج موجودیت، به طور پیشفرض زمان فعلی را تنظیم میکند. این ویژگی زمانی که موجودیت برای اولین بار ایجاد میشود ثبت میگردد.
public DateTime? UpdateTime { get; set; }:
زمان بهروزرسانی موجودیت، مقدار نالپذیر. این ویژگی زمانی که موجودیت بهروزرسانی میشود ثبت میگردد.
public bool IsRemoved { get; set; } = false;:
وضعیت حذف موجودیت، به طور پیشفرض مقدار false دارد. این ویژگی نشان میدهد که آیا موجودیت حذف شده است یا خیر.
public DateTime? RemoveTime { get; set; }:
زمان حذف موجودیت، مقدار نالپذیر. این ویژگی زمانی که موجودیت حذف میشود ثبت میگردد.
کاربرد کد:
این کلاس BaseEntityNotId به شما امکان میدهد تا کلاسهای موجودیتهای مختلف را با استفاده از ویژگیهای عمومی مانند زمان درج، زمان بهروزرسانی، وضعیت حذف، و زمان حذف ایجاد کنید. این ساختار به شما کمک میکند تا کدهای خود را سازماندهی کرده و تکرار کدها را کاهش دهید.
نتیجهگیری:
این کد به شما کمک میکند تا کلاسهای موجودیتهای مختلف را به سادگی و با استفاده از کلاس پایه BaseEntityNotId ایجاد کنید. این کلاس ویژگیهای عمومی را تعریف میکند که میتوانند در تمامی موجودیتها استفاده شوند، با این تفاوت که شناسه (Id) در این کلاس وجود ندارد.
Test_Store => Domain => Entities => Products => Category.cs
بیایید کد Category را بررسی کنیم. این کد به منظور تعریف یک دستهبندی در فروشگاه شما طراحی شده است و از کلاس پایه BaseEntity ارثبری میکند.
توضیحات کد:
Namespace:
namespace Test_Store.Domain.Entities.Products:
نامفضا برای سازماندهی کدهای مرتبط با موجودیتهای محصولات.
Class Category:
این کلاس نمایشی از یک دستهبندی در سیستم شماست و از کلاس پایه BaseEntity ارثبری میکند.
Properties:
public string Name { get; set; }:
نام دستهبندی.
public virtual Category ParentCategory { get; set; }:
مرجع به دستهبندی والد، اگر وجود داشته باشد. این خاصیت به صورت virtual تعریف شده است که به Entity Framework اجازه میدهد تا از ویژگیهای بارگذاری تنبل (lazy loading) استفاده کند.
public long? ParentCategoryId { get; set; }:
شناسه دستهبندی والد، اگر وجود داشته باشد.
public virtual ICollection<Category> SubCategories { get; set; }:
مجموعهای از زیر دستهبندیها. این خاصیت نیز به صورت virtual تعریف شده است که به Entity Framework اجازه میدهد تا از ویژگیهای بارگذاری تنبل استفاده کند.
نتیجهگیری:
این کد به شما امکان میدهد تا دستهبندیها و زیر دستهبندیهای مرتبط را در سیستم خود تعریف کنید. کلاس Category شامل ویژگیهایی برای نام دستهبندی، دستهبندی والد، شناسه دستهبندی والد و مجموعهای از زیر دستهبندیهاست. با استفاده از این ساختار، میتوانید سلسله مراتب دستهبندیهای محصولات خود را به راحتی مدیریت کنید.
Test_Store => Domain => Entities => Users => Role.cs
بیایید کد Role را بررسی کنیم. این کد به منظور تعریف نقشها در سیستم شما طراحی شده است و از کلاس پایه BaseEntity ارثبری میکند.
توضیحات کد:
Namespace:
namespace Test_Store.Domain.Entities.Users:
نامفضا برای سازماندهی کدهای مرتبط با موجودیتهای کاربران.
Class Role:
این کلاس نمایشی از یک نقش در سیستم شماست و از کلاس پایه BaseEntity ارثبری میکند.
Properties:
public string Name { get; set; }:
نام نقش.
public ICollection<UserInRole> UserInRoles { get; set; }:
مجموعهای از UserInRole ها که ارتباط بین کاربران و نقشها را نشان میدهد. این ویژگی به شما امکان میدهد تا چندین کاربر با چندین نقش را مدیریت کنید.
نتیجهگیری:
این کد به شما امکان میدهد تا نقشها را در سیستم خود تعریف و مدیریت کنید. کلاس Role شامل ویژگیهایی برای نام نقش و مجموعهای از UserInRole هاست که نشاندهنده ارتباط بین کاربران و نقشهاست. با استفاده از این ساختار، میتوانید نقشهای مختلف را به کاربران اختصاص دهید و به راحتی سیستمهای دسترسی و مجوزها را مدیریت کنید.
Test_Store => Domain => Entities => Users => User.cs
بیایید کد User را بررسی کنیم. این کد به منظور تعریف یک کاربر در سیستم شما طراحی شده است و از کلاس پایه BaseEntity ارثبری میکند.
توضیحات کد:
Namespace:
namespace Test_Store.Domain.Entities.Users:
نامفضا برای سازماندهی کدهای مرتبط با موجودیتهای کاربران.
Class User:
این کلاس نمایشی از یک کاربر در سیستم شماست و از کلاس پایه BaseEntity ارثبری میکند.
Properties:
public string FullName { get; set; }:
نام کامل کاربر.
public string Email { get; set; }:
ایمیل کاربر.
public string Password { get; set; }:
رمز عبور هش شدهی کاربر.
public bool IsActive { get; set; }:
وضعیت فعالیت کاربر. این ویژگی نشان میدهد که آیا کاربر فعال است یا خیر.
public ICollection<UserInRole> UserInRoles { get; set; }:
مجموعهای از UserInRole ها که ارتباط بین کاربران و نقشها را نشان میدهد. این ویژگی به شما امکان میدهد تا چندین نقش به کاربر اختصاص دهید و دسترسیهای مختلف را مدیریت کنید.
نتیجهگیری:
این کد به شما امکان میدهد تا کاربران را در سیستم خود تعریف و مدیریت کنید. کلاس User شامل ویژگیهایی برای نام کامل، ایمیل، رمز عبور، وضعیت فعالیت، و مجموعهای از UserInRole هاست که نشاندهنده ارتباط بین کاربران و نقشهاست. با استفاده از این ساختار، میتوانید اطلاعات کاربر را به صورت منظم و یکپارچه ذخیره کرده و مدیریت کنید.
Test_Store => Domain => Entities => Users => UserInRole.cs
بیایید کد UserInRole را بررسی کنیم. این کد به منظور تعریف ارتباط بین کاربران و نقشها در سیستم شما طراحی شده است و از کلاس پایه BaseEntity ارثبری میکند.
توضیحات کد:
Namespace:
namespace Test_Store.Domain.Entities.Users:
نامفضا برای سازماندهی کدهای مرتبط با موجودیتهای کاربران.
Class UserInRole:
این کلاس نمایشی از یک ارتباط بین کاربر و نقش در سیستم شماست و از کلاس پایه BaseEntity ارثبری میکند.
Properties:
public long Id { get; set; }:
شناسه این ارتباط.
public virtual User User { get; set; }:
مرجع به کاربر. این خاصیت به صورت virtual تعریف شده است که به Entity Framework اجازه میدهد تا از ویژگیهای بارگذاری تنبل (lazy loading) استفاده کند.
public long UserId { get; set; }:
شناسه کاربر.
public virtual Role Role { get; set; }:
مرجع به نقش. این خاصیت به صورت virtual تعریف شده است که به Entity Framework اجازه میدهد تا از ویژگیهای بارگذاری تنبل استفاده کند.
public long RoleId { get; set; }:
شناسه نقش.
نحوه عملکرد:
این کلاس UserInRole به شما امکان میدهد تا ارتباط بین کاربران و نقشها را در سیستم خود تعریف و مدیریت کنید. با استفاده از ویژگیهای User و Role، میتوانید اطلاعات کاربر و نقش مرتبط را دریافت و تنظیم کنید. شناسههای UserId و RoleId نیز به شما کمک میکنند تا به راحتی این ارتباطات را مدیریت کنید.
نتیجهگیری:
این کد به شما امکان میدهد تا ارتباطات بین کاربران و نقشها را به سادگی تعریف و مدیریت کنید. کلاس UserInRole شامل ویژگیهایی برای شناسه، کاربر، شناسه کاربر، نقش و شناسه نقش است. با استفاده از این ساختار، میتوانید ارتباطات چند به چند بین کاربران و نقشها را به راحتی مدیریت کنید و دسترسیها و مجوزها را کنترل کنید.
Test_Store => Persistence => Context => DataBaseContext.cs
بیایید کد DataBaseContext را بررسی کنیم. این کلاس به منظور مدیریت ارتباط بین دیتابیس و برنامه شما طراحی شده است و از کلاس DbContext ارثبری میکند. این کلاس مسئولیت تعریف جداول و پیکربندی مدلهای داده را بر عهده دارد.
توضیحات کد:
Namespace:
namespace Test_Store.Persistence.Context: نامفضا برای سازماندهی کدهای مرتبط با مدیریت دیتابیس.
Class DataBaseContext:
این کلاس نمایشی از دیتابیس کانتکست است که از کلاس DbContext ارثبری میکند و اینترفیس IDataBaseContext را پیادهسازی میکند.
Constructor:
public DataBaseContext(DbContextOptions options) : base(options):
سازنده کلاس که از DbContextOptions به عنوان پارامتر ورودی استفاده میکند و آن را به سازنده پایه (DbContext) ارسال میکند.
DbSet Properties:
این ویژگیها جداول مختلف دیتابیس را تعریف میکنند:
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<UserInRole> UserInRoles { get; set; }
public DbSet<Category> Categories { get; set; }
Method OnModelCreating:
protected override void OnModelCreating(ModelBuilder modelBuilder):
این متد برای پیکربندی مدلها و تعریف قوانین خاص هنگام ایجاد مدل استفاده میشود.
Seed Data:
SeedData(modelBuilder):
این متد دادههای اولیه (seed data) را به مدل اضافه میکند.
اعمال ایندکس بر روی فیلد ایمیل:
modelBuilder.Entity<User>().HasIndex(u => u.Email).IsUnique():
این خط کد یک ایندکس یکتا بر روی فیلد Email جدول User ایجاد میکند تا از تکراری بودن ایمیل جلوگیری کند.
اعمال عدم نمایش اطلاعات حذف شده:
ApplyQueryFilter(modelBuilder):
این متد برای فیلتر کردن رکوردهای حذف شده (با استفاده از ویژگی IsRemoved) در جداول مختلف استفاده میشود.
Method ApplyQueryFilter:
private void ApplyQueryFilter(ModelBuilder modelBuilder):
این متد فیلترهای کوئری را برای جداول مختلف اعمال میکند تا رکوردهای حذف شده نمایش داده نشوند:
modelBuilder.Entity<User>().HasQueryFilter(p => !p.IsRemoved)
modelBuilder.Entity<Role>().HasQueryFilter(p => !p.IsRemoved)
modelBuilder.Entity<UserInRole>().HasQueryFilter(p => !p.IsRemoved)
modelBuilder.Entity<Category>().HasQueryFilter(p => !p.IsRemoved)
Method SeedData:
private void SeedData(ModelBuilder modelBuilder):
این متد دادههای اولیه (seed data) را به مدل اضافه میکند:
modelBuilder.Entity<Role>().HasData(new Role { Id = 1, Name = nameof(UserRoles.Admin) })
modelBuilder.Entity<Role>().HasData(new Role { Id = 2, Name = nameof(UserRoles.Operator) })
modelBuilder.Entity<Role>().HasData(new Role { Id = 3, Name = nameof(UserRoles.Customer) })
Method OnConfiguring:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder):
این متد برای پیکربندی گزینههای دیتابیس کانتکست استفاده میشود. در اینجا، از متد ConfigureWarnings استفاده شده است تا هشدارهای مربوط به تغییرات مدل معلق (pending model changes) نادیده گرفته شود.
نتیجهگیری:
این کد به شما امکان میدهد تا جداول مختلف دیتابیس را تعریف و پیکربندی کنید، دادههای اولیه (seed data) را اضافه کنید و فیلترهای کوئری را برای عدم نمایش رکوردهای حذف شده اعمال کنید. همچنین از متد ConfigureWarnings برای نادیدهگرفتن هشدارهای مربوط به تغییرات مدل معلق استفاده میکند.
Test_Store => Persistence => Migrations => DataBaseContextModelSnapshot.cs
وقتی مایگریشن جدید می سازیم این کد ساخته می شود
بیایید کد DataBaseContextModelSnapshot را بررسی کنیم. این کد مربوط به یک مدل اسنپشات (snapshot) در فرآیند مایگریشن است و برای ذخیرهی وضعیت کنونی مدل دیتابیس استفاده میشود. مدل اسنپشات به Entity Framework Core کمک میکند تا تفاوتهای بین مدل فعلی و نسخههای قبلی را تشخیص دهد.
توضیحات کد:
Namespace:
namespace Test_Store.Persistence.Migrations:
نامفضا برای سازماندهی کدهای مرتبط با مایگریشنها.
Attribute [DbContext(typeof(DataBaseContext))]:
این ویژگی نشان میدهد که این اسنپشات به کلاس DataBaseContext مرتبط است.
Class DataBaseContextModelSnapshot:
این کلاس جزئی از فرآیند مایگریشن است و از ModelSnapshot ارثبری میکند.
Method BuildModel:
این متد مدل دیتابیس را بازسازی میکند.
متد BuildModel:
protected override void BuildModel(ModelBuilder modelBuilder):
این متد برای بازسازی مدل دیتابیس استفاده میشود.
اعلانها (Annotations):
modelBuilder.HasAnnotation("ProductVersion", "9.0.0"):
نسخه محصول را مشخص میکند.
modelBuilder.HasAnnotation("Relational:MaxIdentifierLength", 128): حداکثر طول شناسههای رابطهای را مشخص میکند.
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder): استفاده از ستونهای هویت در SQL Server.
تعریف جداول:
Entity "Category":
b.Property<long>("Id").ValueGeneratedOnAdd().HasColumnType("bigint"):
ستون Id که به طور خودکار تولید میشود و از نوع bigint است.
سایر ستونها مانند InsertTime, IsRemoved, Name, ParentCategoryId, RemoveTime, و UpdateTime نیز تعریف شدهاند.
b.HasKey("Id"):
کلید اصلی.
b.HasIndex("ParentCategoryId"):
ایندکس بر روی ستون ParentCategoryId.
b.ToTable("Categories"):
نام جدول.
Entity "Role":
ستونها و کلیدها مشابه تعریف شدهاند.
Seed Data:
b.HasData(new { Id = 1L, InsertTime = ... }): دادههای اولیه برای جدول Roles.
Entity "User":
ستونها و کلیدها مشابه تعریف شدهاند.
b.HasIndex("Email").IsUnique():
ایندکس یکتا بر روی ستون Email.
Entity "UserInRole":
ستونها و کلیدها مشابه تعریف شدهاند.
ایندکسها بر روی RoleId و UserId.
تعریف روابط:
Relation "Category":
b.HasOne("Test_Store.Domain.Entities.Products.Category", "ParentCategory").WithMany("SubCategories").HasForeignKey("ParentCategoryId"):
رابطه والد و زیر دستهبندیها.
Relation "UserInRole":
b.HasOne("Test_Store.Domain.Entities.Users.Role", "Role").WithMany("UserInRoles").HasForeignKey("RoleId").OnDelete(DeleteBehavior.Cascade).IsRequired():
رابطه بین UserInRole و Role.
b.HasOne("Test_Store.Domain.Entities.Users.User", "User").WithMany("UserInRoles").HasForeignKey("UserId").OnDelete(DeleteBehavior.Cascade).IsRequired():
رابطه بین UserInRole و User.
نتیجهگیری:
این کد به شما امکان میدهد تا وضعیت کنونی مدل دیتابیس را به صورت یک اسنپشات ذخیره کنید. با استفاده از این اسنپشات، Entity Framework میتواند تفاوتهای بین مدلهای فعلی و قبلی را شناسایی کند و مایگریشنهای مناسب را ایجاد کند. این شامل تعریف جداول، ستونها، روابط و دادههای اولیه (seed data) است.
EndPoint.Site => Controllers => AuthenticationController.cs
بیایید کد AuthenticationController را بررسی کنیم. این کنترلر به منظور مدیریت عملیاتهای احراز هویت و ثبتنام کاربران طراحی شده است و شامل متدهایی برای ثبتنام، ورود، و خروج کاربران میباشد.
توضیحات کد:
Namespace:
namespace EndPoint.Site.Controllers:
نامفضا برای سازماندهی کدهای مرتبط با کنترلرهای سایت.
Class AuthenticationController:
این کلاس از Controller ارثبری میکند و شامل متدهایی برای احراز هویت کاربران است.
Dependencies:
private readonly IRegisterUserService _registerUserService;
private readonly IUserLoginService _userLoginService;
Constructor:
سازنده کلاس که سرویسهای IRegisterUserService و IUserLoginService را دریافت میکند.
csharp
public AuthenticationController(IRegisterUserService registerUserService, IUserLoginService userLoginService)
{
_registerUserService = registerUserService;
_userLoginService = userLoginService;
}
Method Signup:
HttpGet:
نمایش صفحه ثبتنام.
csharp
[HttpGet]
public IActionResult Signup()
{
return View();
}
HttpPost: پردازش فرم ثبتنام.
csharp
[HttpPost]
public IActionResult Signup(SignupViewModel request)
{
// بررسی صحت اطلاعات ورودی
if (string.IsNullOrWhiteSpace(request.FullName) ||
string.IsNullOrWhiteSpace(request.Email) ||
string.IsNullOrWhiteSpace(request.Password) ||
string.IsNullOrWhiteSpace(request.RePassword))
{
return Json(new ResultDto { IsSuccess = false, Message = "لطفا تمامی موارد رو ارسال نمایید" });
}
if (User.Identity.IsAuthenticated == true)
{
return Json(new ResultDto { IsSuccess = false, Message = "شما به حساب کاربری خود وارد شده اید! و در حال حاضر نمیتوانید ثبت نام مجدد نمایید" });
}
if (request.Password != request.RePassword)
{
return Json(new ResultDto { IsSuccess = false, Message = "رمز عبور و تکرار آن برابر نیست" });
}
if (request.Password.Length < 8)
{
return Json(new ResultDto { IsSuccess = false, Message = "رمز عبور باید حداقل 8 کاراکتر باشد" });
}
// بررسی صحت ایمیل
string emailRegex = @"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Z0-9.-]+\.[A-Z]{2,}$";
var match = Regex.Match(request.Email, emailRegex, RegexOptions.IgnoreCase);
if (!match.Success)
{
return Json(new ResultDto { IsSuccess = true, Message = "ایمیل خودرا به درستی وارد نمایید" });
}
// ثبتنام کاربر
var signeupResult = _registerUserService.Execute(new RequestRegisterUserDto
{
Email = request.Email,
FullName = request.FullName,
Password = request.Password,
RePasword = request.RePassword,
roles = new List<RolesInRegisterUserDto>() { new RolesInRegisterUserDto { Id = 3 } }
});
if (signeupResult.IsSuccess == true)
{
// ایجاد ادعاها (claims) برای کاربر ثبتنام شده
var claims = new List<Claim>()
{
new Claim(ClaimTypes.NameIdentifier, signeupResult.Data.UserId.ToString()),
new Claim(ClaimTypes.Email, request.Email),
new Claim(ClaimTypes.Name, request.FullName),
new Claim(ClaimTypes.Role, "Customer")
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
var properties = new AuthenticationProperties() { IsPersistent = true };
HttpContext.SignInAsync(principal, properties);
}
return Json(signeupResult);
}
Method Signin:
HttpGet:
نمایش صفحه ورود.
csharp
public IActionResult Signin(string ReturnUrl = "/")
{
ViewBag.url = ReturnUrl;
return View();
}
HttpPost:
پردازش فرم ورود.
csharp
[HttpPost]
public IActionResult Signin(string Email, string Password, string url = "/")
{
var signupResult = _userLoginService.Execute(Email, Password);
if (signupResult.IsSuccess == true)
{
// ایجاد ادعاها (claims) برای کاربر وارد شده
var claims = new List<Claim>()
{
new Claim(ClaimTypes.NameIdentifier, signupResult.Data.UserId.ToString()),
new Claim(ClaimTypes.Email, Email),
new Claim(ClaimTypes.Name, signupResult.Data.Name),
new Claim(ClaimTypes.Role, signupResult.Data.Roles)
};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
var properties = new AuthenticationProperties()
{
IsPersistent = true,
ExpiresUtc = DateTime.Now.AddDays(5)
};
HttpContext.SignInAsync(principal, properties);
}
return Json(signupResult);
}
Method SignOut:
خروج کاربر و پایان جلسه احراز هویت.
csharp
public IActionResult SignOut()
{
HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return RedirectToAction("Index", "Home");
}
نتیجهگیری:
این کنترلر AuthenticationController به شما امکان میدهد تا عملیاتهای ثبتنام، ورود، و خروج کاربران را به سادگی مدیریت کنید. متدهای Signup و Signin شامل بررسیهای اولیه و ایجاد ادعاهای (claims) کاربران برای احراز هویت آنهاست. متد SignOut نیز برای خروج کاربران و پایان دادن به جلسه احراز هویت استفاده میشود.