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 نیز برای خروج کاربران و پایان دادن به جلسه احراز هویت استفاده میشود.
EndPoint.Site => Models => ViewModels => AuthenticationViewModel => SignupViewModel.cs
بیایید کد SignupViewModel را بررسی کنیم. این کلاس نمایشی (ViewModel) برای فرم ثبتنام کاربران در سیستم شما است.
توضیحات کد:
Namespace:
namespace EndPoint.Site.Models.ViewModels.AuthenticationViewModel:
نامفضا برای سازماندهی کدهای مرتبط با مدلهای نمایشی احراز هویت.
Class SignupViewModel:
این کلاس برای نگهداری دادههای ورودی فرم ثبتنام کاربران استفاده میشود.
Properties:
public string FullName { get; set; } = "";:
نام کامل کاربر. این ویژگی یک مقدار پیشفرض خالی (رشتهی خالی) دارد.
public string Email { get; set; }:
ایمیل کاربر.
public string Password { get; set; }:
رمز عبور کاربر.
public string RePassword { get; set; }:
تکرار رمز عبور برای تأیید صحت رمز عبور.
نتیجهگیری:
این کلاس SignupViewModel به شما امکان میدهد تا دادههای ورودی فرم ثبتنام کاربران را به صورت منظم و ساختاریافته نگهداری کنید. ویژگیهای این کلاس شامل نام کامل، ایمیل، رمز عبور، و تکرار رمز عبور است که همه برای ثبتنام کاربران ضروری هستند.
بخشی از کد Layout می باشد
<div class="col-lg-3 col-md-3 col-xs-12 pl">
<div class="header-left">
<div class="header-account text-left">
<div class="d-block">
<div class="account-box">
@if (User.Identity.IsAuthenticated)
{
<div class="nav-account d-block pl">
<span class="icon-account">
<img src="~/sitetemplate/img/man.png" class="avator" />
</span>
<span class="title-account">@User.Identity.Name</span>
<div class="dropdown-menu">
<ul class="account-uls mb-0">
<li class="account-item">
<a href="#" class="account-link">پنل کاربری</a>
</li>
<li class="account-item">
<a href="#" class="account-link">سفارشات من</a>
</li>
<li class="account-item">
<a href="#" class="account-link">تنظیمات</a>
</li>
<li class="account-item">
<a href="~/authentication/SignOut" class="account-link">خروج</a>
</li>
</ul>
</div>
</div>
}
else
{
<div class="nav-account d-block pl">
<a href="~/authentication/signup">
<span class="title-account">ثبت نام</span>
</a>
<a href="~/authentication/signin">
<span class="title-account">ورود</span>
</a>
</div>
}
بیایید بخشی کد layout که برای مدیریت نمایش اطلاعات کاربری و لینکهای ورود و ثبتنام استفاده میشود را بررسی کنیم. این کد به منظور نمایش اطلاعات مختلف بر اساس وضعیت احراز هویت کاربر استفاده میشود.
توضیحات کد:
ساختار اصلی:
کد داخل یک div با کلاسهای col-lg-3 col-md-3 col-xs-12 pl قرار دارد که به کمک کلاسهای Bootstrap برای طراحی واکنشگرا (responsive) استفاده میشود.
قسمتهای اصلی:
div.header-left: بخش چپ هدر.
div.header-account: بخش مربوط به حساب کاربری با متنی به سمت چپ.
div.d-block: بخش با نمایش بلوکی (block).
بررسی وضعیت احراز هویت:
کد @if (User.Identity.IsAuthenticated) برای بررسی وضعیت احراز هویت کاربر استفاده میشود.
اگر کاربر احراز هویت شده باشد:
div.nav-account:
نمایش اطلاعات حساب کاربری.
span.icon-account:
نمایش تصویر پروفایل کاربر.
تصویر پروفایل از مسیر ~/sitetemplate/img/man.png بارگذاری میشود و کلاس avator برای آن تنظیم شده است.
span.title-account:
نمایش نام کاربر با استفاده از @User.Identity.Name.
div.dropdown-menu:
منوی کشویی برای نمایش لینکهای مختلف.
ul.account-uls:
لیست لینکهای حساب کاربری.
li.account-item:
آیتمهای لیست.
a.account-link:
لینکهای پنل کاربری، سفارشات من، تنظیمات و خروج.
اگر کاربر احراز هویت نشده باشد:
div.nav-account: نمایش لینکهای ثبتنام و ورود.
a: لینک برای نمایش فرم ثبتنام.
span.title-account:
متن لینک ثبتنام.
a: لینک برای نمایش فرم ورود.
span.title-account:
متن لینک ورود.
نتیجهگیری:
این کد به صورت پویا وضعیت احراز هویت کاربر را بررسی میکند و بر اساس آن، اطلاعات حساب کاربری یا لینکهای ثبتنام و ورود را نمایش میدهد. در صورتی که کاربر احراز هویت شده باشد، تصویر پروفایل، نام کاربر و لینکهای پنل کاربری، سفارشات من، تنظیمات و خروج نمایش داده میشود. در غیر این صورت، لینکهای ثبتنام و ورود نمایش داده میشوند.
EndPoint.Site => Views => Authentication => Signin.cshtml
بیایید کد صفحه ورود (Signin) را بررسی کنیم. این کد به منظور نمایش فرم ورود کاربران و مدیریت عملیات ورود استفاده میشود.
توضیحات کد:
ViewData و Layout:
csharp
@{
ViewData["Title"] = "Signin";
Layout = null;
}
ViewData["Title"]: عنوان صفحه را به "Signin" تنظیم میکند.
Layout = null:
استفاده از layout پیشفرض را غیرفعال میکند و صفحه را به عنوان یک صفحه مستقل نمایش میدهد.
HTML ساختار اصلی:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>پنل مدیریت | صفحه ورود</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="~/sweetalert2/sweetalert2.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<link rel="stylesheet" href="~/AdminTemplate/dist/css/adminlte.min.css">
<link rel="stylesheet" href="~/AdminTemplate/plugins/iCheck/square/blue.css">
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
<link rel="stylesheet" href="~/AdminTemplate/dist/css/bootstrap-rtl.min.css">
<link rel="stylesheet" href="~/AdminTemplate/dist/css/custom-style.css">
</head>
تنظیم متا تگها برای اطمینان از واکنشگرایی (responsive) صفحه.
لینک به فایلهای CSS مختلف از جمله Font Awesome, Ionicons, AdminLTE، و bootstrap-rtl.
بدنه صفحه:
html
<body class="hold-transition login-page">
<div class="login-box">
<div class="login-logo">
<a href="#"><b>ورود به سایت</b></a>
</div>
<div class="card">
<div class="card-body login-card-body">
<p class="login-box-msg">فرم زیر را تکمیل کنید و ورود بزنید</p>
<form method="post">
<div class="input-group mb-3">
<input type="email" class="form-control" id="Email" placeholder="ایمیل">
<div class="input-group-append">
<span class="fa fa-envelope input-group-text"></span>
</div>
</div>
<div class="input-group mb-3">
<input type="password" class="form-control" id="Password" placeholder="رمز عبور">
<div class="input-group-append">
<span class="fa fa-lock input-group-text"></span>
</div>
</div>
<div class="row">
<div class="col-8">
<div class="checkbox icheck">
<label>
<input type="checkbox" value="1" name="login" id="remember"> مرا به خاطر بسپار
</label>
</div>
</div>
<div class="col-4">
<button type="button" onclick="Login()" class="btn btn-primary btn-block btn-flat">ورود</button>
</div>
</div>
</form>
<p class="mb-1">
<a href="#">رمز عبورم را فراموش کرده ام.</a>
</p>
<p class="mb-0">
<a href="~/authentication/signup" class="text-center">ورود به ثبت نام</a>
</p>
</div>
</div>
</div>
فرم ورود با فیلدهای ایمیل و رمز عبور.
گزینه "مرا به خاطر بسپار".
دکمه ورود که با کلیک بر روی آن، تابع Login فراخوانی میشود.
JavaScript:
html
<script src="~/AdminTemplate/plugins//jquery/jquery.min.js"></script>
<script src="~/AdminTemplate/plugins//bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="~/AdminTemplate/plugins//iCheck/icheck.min.js"></script>
<link href="~/Sweetalert2/sweetalert2.min.css" rel="stylesheet" />
<script src="~/Sweetalert2/sweetalert2.min.js"></script>
<script>
function Login() {
var Email = $("#Email").val();
var Password = $("#Password").val();
var postData = {
'Email': Email,
'Password': Password,
};
$.ajax({
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
type: "POST",
url: "Signin",
data: postData,
success: function (data) {
if (data.isSuccess == true) {
swal.fire(
'موفق!',
data.message,
'success'
).then(function (isConfirm) {
window.location.replace("/");
});
}
else {
swal.fire(
'هشدار!',
data.message,
'warning'
);
}
},
error: function (request, status, error) {
swal.fire(
'هشدار!',
request.responseText,
'warning'
);
}
});
}
</script>
</body>
</html>
استفاده از jQuery, Bootstrap, iCheck, و Sweetalert2 برای بهبود عملکرد و ظاهر صفحه.
تابع Login که با استفاده از AJAX درخواست ورود را به سرور ارسال میکند و بر اساس پاسخ سرور، پیامهای مناسب را نمایش میدهد.
نتیجهگیری:
این صفحه ورود به کاربران اجازه میدهد تا اطلاعات ورود خود را وارد کنند و عملیات ورود را انجام دهند. همچنین در صورت موفقیت یا خطا در ورود، پیامهای مناسبی نمایش داده میشود. استفاده از AJAX برای ارسال درخواست ورود به سرور و مدیریت پاسخها باعث بهبود تجربه کاربری میشود.
EndPoint.Site => Views => Authentication => Signup.cshtml
بیایید کد صفحه ثبتنام (Signup) را بررسی کنیم. این کد به منظور نمایش فرم ثبتنام کاربران و مدیریت عملیات ثبتنام استفاده میشود.
توضیحات کد:
ViewData و Layout:
csharp
@{
ViewData["Title"] = "ثبت نام";
Layout = null;
}
ViewData["Title"]:
عنوان صفحه را به "ثبت نام" تنظیم میکند.
Layout = null:
استفاده از layout پیشفرض را غیرفعال میکند و صفحه را به عنوان یک صفحه مستقل نمایش میدهد.
HTML ساختار اصلی:
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>پنل مدیریت | صفحه ثبت نام</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="~/sweetalert2/sweetalert2.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css">
<link rel="stylesheet" href="~/AdminTemplate/dist/css/adminlte.min.css">
<link rel="stylesheet" href="~/AdminTemplate/plugins/iCheck/square/blue.css">
<link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
<link rel="stylesheet" href="~/AdminTemplate/dist/css/bootstrap-rtl.min.css">
<link rel="stylesheet" href="~/AdminTemplate/dist/css/custom-style.css">
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
</head>
تنظیم متا تگها برای اطمینان از واکنشگرایی (responsive) صفحه.
لینک به فایلهای CSS مختلف از جمله Font Awesome, Ionicons, AdminLTE, bootstrap-rtl، و SweetAlert2.
بدنه صفحه:
html
<body class="hold-transition register-page">
<div class="register-box">
<div class="register-logo">
<b>ثبت نام در سایت</b>
</div>
<div class="card">
<div class="card-body register-card-body">
<p class="login-box-msg">ثبت نام کاربر جدید</p>
<form method="post">
<div class="input-group mb-3">
<input type="text" class="form-control" id="FullName" placeholder="نام و نام خانوادگی">
<div class="input-group-append">
<span class="fa fa-user input-group-text"></span>
</div>
</div>
<div class="input-group mb-3">
<input type="email" class="form-control" id="Email" placeholder="ایمیل">
<div class="input-group-append">
<span class="fa fa-envelope input-group-text"></span>
</div>
</div>
<div class="input-group mb-3">
<input type="password" class="form-control" placeholder="رمز عبور" id="Password">
<div class="input-group-append">
<span class="fa fa-lock input-group-text"></span>
</div>
</div>
<div class="input-group mb-3">
<input type="password" class="form-control" placeholder="تکرار رمز عبور" id="RePassword">
<div class="input-group-append">
<span class="fa fa-lock input-group-text"></span>
</div>
</div>
<div class="row">
<div class="col-8">
<div class="checkbox icheck">
<label>
<input type="checkbox" value="1" name="login" id="remember"> با <a href="#">شرایط</a> موافق هستم
</label>
</div>
</div>
<div class="col-4">
<button onclick="Registeruser()" type="button" class="btn btn-primary btn-block btn-flat">ثبت نام</button>
</div>
</div>
</form>
<a href="~/authentication/signin" class="text-center">من قبلا ثبت نام کرده ام</a>
</div>
</div>
</div>
فرم ثبتنام با فیلدهای نام کامل، ایمیل، رمز عبور، و تکرار رمز عبور.
گزینه "با شرایط موافق هستم".
دکمه ثبتنام که با کلیک بر روی آن، تابع Registeruser فراخوانی میشود.
لینک به صفحه ورود برای کاربران که قبلاً ثبتنام کردهاند.
JavaScript:
html
<script src="~/AdminTemplate/plugins/jquery/jquery.min.js"></script>
<script src="~/AdminTemplate/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="~/AdminTemplate/plugins//iCheck/icheck.min.js"></script>
<link href="~/Sweetalert2/sweetalert2.min.css" rel="stylesheet" />
<script src="~/sweetalert2/sweetalert2.min.js"></script>
<script>
function Registeruser() {
var FullName = $("#FullName").val();
var Email = $("#Email").val();
var Password = $("#Password").val();
var RePassword = $("#RePassword").val();
var postData = {
'FullName': FullName,
'Email': Email,
'Password': Password,
'RePassword': RePassword,
};
$.ajax({
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
type: "POST",
url: "Signup",
data: postData,
success: function (data) {
if (data.isSuccess == true) {
swal.fire(
'موفق!',
data.message,
'success'
).then(function (isConfirm) {
window.location.replace("/");
});
} else {
swal.fire(
'هشدار!',
data.message,
'warning'
);
}
},
error: function (request, status, error) {
swal.fire(
'هشدار!',
request.responseText,
'warning'
);
}
});
}
</script>
</body>
</html>
استفاده از jQuery, Bootstrap, iCheck, و SweetAlert2 برای بهبود عملکرد و ظاهر صفحه.
تابع Registeruser که با استفاده از AJAX درخواست ثبتنام را به سرور ارسال میکند و بر اساس پاسخ سرور، پیامهای مناسب را نمایش میدهد.
نتیجهگیری:
این صفحه ثبتنام به کاربران اجازه میدهد تا اطلاعات خود را وارد کرده و عملیات ثبتنام را انجام دهند. همچنین در صورت موفقیت یا خطا در ثبتنام، پیامهای مناسبی نمایش داده میشود. استفاده از AJAX برای ارسال درخواست ثبتنام به سرور و مدیریت پاسخها باعث بهبود تجربه کاربری میشود.
در packing manager console عبارت Add-Migration Test یا هر نامی که قابل فهم باشد و بعد Update-Database وارد کنید
نکته ای که نگفتم این هست که :
لیست را در قسمت Test_Store.Persistence باشد تا مایگریشن ساخته شود