eitaa logo
پروژه ASP.Net Core MVC (وب و سی شارپ)
121 دنبال‌کننده
168 عکس
38 ویدیو
376 فایل
❁﷽❁ آموزش 📖 برنامه نویسی ASP.Net Core MVC (وب و سی شارپ) Admin: @alialirezapanahi برنامه نویسی برنامه نویسی سی شارپ eitaa.com/sisharpapp برنامه نویسی وب eitaa.com/aspdatnet ویراستی virasty.com/alialirezapanahi آپارات aparat.com/alialirezapanahi
مشاهده در ایتا
دانلود
Test_Store.Application => Services => Users => Queries => GetRoles => IGetRolesService.cs نام‌فضا (Namespace) csharp namespace Test_Store.Application.Services.Users.Queries.GetRoles این خط، نام‌فضا (namespace) Test_Store.Application.Services.Users.Queries.GetRoles را تعریف می‌کند. نام‌فضاها برای سازماندهی و دسته‌بندی کدها استفاده می‌شوند. کلاس GetRolesService این کلاس پیاده‌سازی اینترفیس IGetRolesService است و شامل منطق اصلی برای دریافت نقش‌ها از پایگاه داده است. تعریف کلاس و سازنده csharp public class GetRolesService : IGetRolesService { private readonly IDataBaseContext _context; public GetRolesService(IDataBaseContext context) { _context = context; } private readonly IDataBaseContext _context;: این خط یک متغیر خصوصی و فقط خواندنی به نام _context از نوع IDataBaseContext تعریف می‌کند که برای دسترسی به پایگاه داده استفاده می‌شود. public GetRolesService(IDataBaseContext context): این سازنده کلاس است که یک نمونه از IDataBaseContext را به عنوان ورودی می‌پذیرد و آن را به متغیر _context اختصاص می‌دهد. متد Execute csharp public ResultDto<List<RolesDto>> Execute() { var roles = _context.Roles.ToList().Select(p => new RolesDto { Id = p.Id, Name = p.Name }).ToList(); return new ResultDto<List<RolesDto>>() { Data = roles, IsSuccess = true, Massage = "", }; } var roles = _context.Roles.ToList().Select(p => new RolesDto { Id = p.Id, Name = p.Name }).ToList();: این خط، تمام نقش‌ها را از پایگاه داده دریافت کرده و هر نقش را به یک شیء RolesDto تبدیل می‌کند. در نهایت، این لیست از نقش‌ها را در متغیر roles ذخیره می‌کند. _context.Roles.ToList(): تمام نقش‌ها را به صورت لیستی از پایگاه داده دریافت می‌کند. .Select(p => new RolesDto { Id = p.Id, Name = p.Name }): هر عنصر لیست را به یک شیء RolesDto تبدیل می‌کند. .ToList(): نتیجه نهایی را به یک لیست تبدیل می‌کند. return new ResultDto<List<RolesDto>>() { Data = roles, IsSuccess = true, Massage = "" };: این خط یک شیء ResultDto<List<RolesDto>> جدید ایجاد کرده و آن را بازمی‌گرداند. این شیء شامل داده‌های نقش‌ها (roles)، وضعیت موفقیت (IsSuccess = true) و پیام (Massage = "") است. نتیجه‌گیری این کد یک سرویس برای دریافت نقش‌ها از پایگاه داده پیاده‌سازی می‌کند. این سرویس نقش‌ها را دریافت کرده و به فرمتی که می‌تواند به کلاینت یا لایه‌های دیگر ارسال شود، برمی‌گرداند. این کلاس از اینترفیس IGetRolesService استفاده می‌کند و نتیجه را به صورت یک شیء ResultDto<List<RolesDto>> بازمی‌گرداند که شامل داده‌ها، وضعیت موفقیت و پیام است.
Test_Store.Application => Services => Users => Queries => GetRoles => RolesDto.cs نام‌فضا (Namespace) csharp namespace Test_Store.Application.Services.Users.Queries.GetRoles این خط، نام‌فضا (namespace) Test_Store.Application.Services.Users.Queries.GetRoles را تعریف می‌کند. نام‌فضاها برای سازماندهی و دسته‌بندی کدها استفاده می‌شوند. کلاس RolesDto csharp public class RolesDto { public long Id { get; set; } public string Name { get; set; } } public class RolesDto: این خط کلاس RolesDto را تعریف می‌کند. Dto مخفف "Data Transfer Object" است که برای انتقال داده‌ها بین لایه‌های مختلف یک برنامه استفاده می‌شود. public long Id { get; set; }: این پراپرتی شناسه‌ی منحصربه‌فرد (ID) برای نقش را نشان می‌دهد. این شناسه از نوع long است. public string Name { get; set; }: این پراپرتی نام نقش را ذخیره می‌کند. این نام از نوع string است. نتیجه‌گیری کلاس RolesDto یک Data Transfer Object (DTO) ساده است که برای انتقال اطلاعات مربوط به نقش‌ها بین لایه‌های مختلف برنامه استفاده می‌شود. این کلاس شامل دو پراپرتی Id و Name است که به ترتیب شناسه و نام نقش را نگهداری می‌کنند.
Test_Store.Application => Services => Users => Queries => GetUsers => ReslutGetUserDto.cs نام‌فضا (Namespace) csharp namespace Test_Store.Application.Services.Users.Queries.GetUsers این خط، نام‌فضا (namespace) Test_Store.Application.Services.Users.Queries.GetUsers را تعریف می‌کند. نام‌فضاها برای سازماندهی و دسته‌بندی کدها استفاده می‌شوند. کلاس ResultGetUserDto csharp public class ResultGetUserDto { public List<GetUsersDto> Users { get; set; } public int Rows { get; set; } } public class ResultGetUserDto: این خط یک کلاس به نام ResultGetUserDto تعریف می‌کند. public List<GetUsersDto> Users { get; set; }: این پراپرتی یک لیست از نوع GetUsersDto را ذخیره می‌کند. این لیست شامل کاربران دریافت شده است. public int Rows { get; set; }: این پراپرتی تعداد کل ردیف‌ها (کاربران) را ذخیره می‌کند. نتیجه‌گیری کلاس ResultGetUserDto یک Data Transfer Object (DTO) است که برای انتقال داده‌های مربوط به کاربران بین لایه‌های مختلف برنامه استفاده می‌شود. این کلاس شامل دو پراپرتی Users (لیست کاربران) و Rows (تعداد کل کاربران) است.
Test_Store.Application => Services => Users => Queries => GetUsers => IGetUsersService.cs نام‌فضا (Namespace) csharp namespace Test_Store.Application.Services.Users.Queries.GetUsers این خط، نام‌فضا (namespace) Test_Store.Application.Services.Users.Queries.GetUsers را تعریف می‌کند. نام‌فضاها برای سازماندهی و دسته‌بندی کدها استفاده می‌شوند. اینترفیس IGetUsersService csharp public interface IGetUsersService { ResultGetUserDto Execute(RequestGetUserDto request); } public interface IGetUsersService: این خط یک اینترفیس به نام IGetUsersService تعریف می‌کند. ResultGetUserDto Execute(RequestGetUserDto request);: این متد در اینترفیس تعریف شده است که یک RequestGetUserDto را به عنوان ورودی می‌پذیرد و یک ResultGetUserDto را به عنوان خروجی برمی‌گرداند. این متد برای دریافت کاربران بر اساس درخواست استفاده می‌شود. نتیجه‌گیری این اینترفیس IGetUsersService برای تعریف یک سرویس است که کاربران را بر اساس یک درخواست دریافت می‌کند. متد Execute شامل ورودی RequestGetUserDto و خروجی ResultGetUserDto است که به شما امکان می‌دهد درخواست‌های کاربر را پردازش کرده و نتایج مربوطه را بازگردانید.
Test_Store.Application => Services => Users => Queries => GetUsers => GetUsersService.cs استفاده از نام‌فضاها (Namespaces) csharp using Test_Store.Application.Interfaces.Contexs; using Test_Store.Common; using Test_Store.Application.Interfaces.Contexs;: این دستور به شما امکان می‌دهد تا از اینترفیس‌ها و کلاس‌های موجود در این نام‌فضا استفاده کنید. using Test_Store.Common;: این دستور به شما امکان می‌دهد تا از کلاس‌ها و امکانات موجود در نام‌فضای Test_Store.Common استفاده کنید. نام‌فضا (Namespace) csharp namespace Test_Store.Application.Services.Users.Queries.GetUsers این خط، نام‌فضا (namespace) Test_Store.Application.Services.Users.Queries.GetUsers را تعریف می‌کند. نام‌فضاها برای سازماندهی و دسته‌بندی کدها استفاده می‌شوند. کلاس GetUsersService این کلاس پیاده‌سازی اینترفیس IGetUsersService است و شامل منطق اصلی برای دریافت کاربران از پایگاه داده است. تعریف کلاس و سازنده csharp public class GetUsersService : IGetUsersService { private readonly IDataBaseContext _context; public GetUsersService(IDataBaseContext context) { _context = context; } private readonly IDataBaseContext _context;: این خط یک متغیر خصوصی و فقط خواندنی به نام _context از نوع IDataBaseContext تعریف می‌کند که برای دسترسی به پایگاه داده استفاده می‌شود. public GetUsersService(IDataBaseContext context): این سازنده کلاس است که یک نمونه از IDataBaseContext را به عنوان ورودی می‌پذیرد و آن را به متغیر _context اختصاص می‌دهد. متد Execute csharp public ResultGetUserDto Execute(RequestGetUserDto request) { var users = _context.Users.AsQueryable(); if (!string.IsNullOrWhiteSpace(request.SearchKey)) { users = users.Where(p => p.FullName.Contains(request.SearchKey) && p.Email.Contains(request.SearchKey)); } int rowsCount = 0; var userList = users.ToPaged(request.Page, 20, out rowsCount).Select(p => new GetUsersDto { Email = p.Email, FullName = p.FullName, Id = p.Id, }).ToList(); return new ResultGetUserDto { Rows = rowsCount, Users = userList, }; } var users = _context.Users.AsQueryable();: این خط تمام کاربران را به صورت یک کوئری قابل پرسش (IQueryable) از پایگاه داده دریافت می‌کند. if (!string.IsNullOrWhiteSpace(request.SearchKey)): این شرط بررسی می‌کند که آیا کلید جستجو (SearchKey) خالی یا فضای خالی نیست. users = users.Where(p => p.FullName.Contains(request.SearchKey) && p.Email.Contains(request.SearchKey));: این خط کاربران را فیلتر می‌کند تا فقط کاربرانی را که کلید جستجو را در نام کامل و ایمیل خود دارند، نمایش دهد. int rowsCount = 0;: این خط یک متغیر برای نگهداری تعداد کل کاربران تنظیم می‌کند. var userList = users.ToPaged(request.Page, 20, out rowsCount).Select(p => new GetUsersDto { Email = p.Email, FullName = p.FullName, Id = p.Id }).ToList();: این خط کاربران را به صفحات کوچکتر تقسیم می‌کند و هر کاربر را به یک شیء GetUsersDto تبدیل می‌کند. users.ToPaged(request.Page, 20, out rowsCount): کاربران را به صفحات تقسیم می‌کند. request.Page شماره صفحه و 20 تعداد آیتم‌ها در هر صفحه است. rowsCount تعداد کل کاربران را ذخیره می‌کند. .Select(p => new GetUsersDto { Email = p.Email, FullName = p.FullName, Id = p.Id }): هر کاربر را به یک شیء GetUsersDto تبدیل می‌کند. .ToList(): نتیجه نهایی را به یک لیست تبدیل می‌کند. return new ResultGetUserDto { Rows = rowsCount, Users = userList };: این خط یک شیء ResultGetUserDto جدید ایجاد کرده و آن را بازمی‌گرداند. این شیء شامل تعداد کل کاربران (rowsCount) و لیست کاربران (userList) است. نتیجه‌گیری این کد یک سرویس برای دریافت کاربران از پایگاه داده پیاده‌سازی می‌کند. این سرویس کاربران را بر اساس کلید جستجو فیلتر کرده، آن‌ها را به صفحات تقسیم کرده و به فرمتی که می‌تواند به کلاینت یا لایه‌های دیگر ارسال شود، برمی‌گرداند. این کلاس از اینترفیس IGetUsersService استفاده می‌کند و نتیجه را به صورت یک شیء ResultGetUserDto بازمی‌گرداند که شامل داده‌ها، تعداد کل کاربران و لیست کاربران است.
Test_Store.Application => Services => Users => Queries => GetUsers => GetUsersDto.cs نام‌فضا (Namespace) csharp namespace Test_Store.Application.Services.Users.Queries.GetUsers این خط، نام‌فضا (namespace) Test_Store.Application.Services.Users.Queries.GetUsers را تعریف می‌کند. نام‌فضاها برای سازماندهی و دسته‌بندی کدها استفاده می‌شوند. کلاس GetUsersDto csharp public class GetUsersDto { public long Id { get; set; } public string FullName { get; set; } public string Email { get; set; } } public class GetUsersDto: این خط کلاس GetUsersDto را تعریف می‌کند. Dto مخفف "Data Transfer Object" است که برای انتقال داده‌ها بین لایه‌های مختلف یک برنامه استفاده می‌شود. public long Id { get; set; }: این پراپرتی شناسه‌ی منحصربه‌فرد (ID) برای کاربر را نشان می‌دهد. این شناسه از نوع long است. public string FullName { get; set; }: این پراپرتی نام کامل کاربر را ذخیره می‌کند. این نام از نوع string است. public string Email { get; set; }: این پراپرتی ایمیل کاربر را ذخیره می‌کند. این ایمیل از نوع string است. نتیجه‌گیری کلاس GetUsersDto یک Data Transfer Object (DTO) ساده است که برای انتقال اطلاعات مربوط به کاربران بین لایه‌های مختلف برنامه استفاده می‌شود. این کلاس شامل سه پراپرتی Id، FullName و Email است که به ترتیب شناسه، نام کامل و ایمیل کاربر را نگهداری می‌کنند.
Test_Store.Application => Services => Users => Queries => GetUsers => RequestGetUserDto.cs نام‌فضا (Namespace) csharp namespace Test_Store.Application.Services.Users.Queries.GetUsers این خط، نام‌فضا (namespace) Test_Store.Application.Services.Users.Queries.GetUsers را تعریف می‌کند. نام‌فضاها برای سازماندهی و دسته‌بندی کدها استفاده می‌شوند. کلاس RequestGetUserDto csharp public class RequestGetUserDto { public string SearchKey { get; set; } public int Page { get; set; } } public class RequestGetUserDto: این خط یک کلاس به نام RequestGetUserDto تعریف می‌کند. public string SearchKey { get; set; }: این پراپرتی یک کلید جستجو (SearchKey) از نوع string را ذخیره می‌کند. این کلید جستجو برای فیلتر کردن کاربران بر اساس نام یا ایمیل استفاده می‌شود. public int Page { get; set; }: این پراپرتی شماره صفحه‌ای (Page) را ذخیره می‌کند که کاربران باید در آن نمایش داده شوند. این ویژگی برای صفحه‌بندی کاربران استفاده می‌شود. نتیجه‌گیری کلاس RequestGetUserDto یک Data Transfer Object (DTO) است که برای انتقال داده‌های مربوط به درخواست دریافت کاربران بین لایه‌های مختلف برنامه استفاده می‌شود. این کلاس شامل دو پراپرتی SearchKey (کلید جستجو) و Page (شماره صفحه) است که به ترتیب برای فیلتر کردن و صفحه‌بندی کاربران استفاده می‌شوند.
اضافه کردن ایترفیس و کلاس ارث بری در program افزودن سرویس‌ها به کانتینر DI (Dependency Injection) csharp builder.Services.AddScoped<IDataBaseContext, DataBaseContext>(); builder.Services.AddScoped<IGetUsersService, GetUsersService>(); builder.Services.AddScoped<IGetRolesService, GetRolesService>(); AddScoped<IDataBaseContext, DataBaseContext>(); تعریف: این خط به DI Container می‌گوید که هر بار که نیاز به IDataBaseContext وجود دارد، یک نمونه از DataBaseContext ایجاد کند. و Scope: Scoped به این معنی است که یک نمونه جدید برای هر درخواست HTTP ساخته می‌شود و تا پایان آن درخواست استفاده می‌شود. AddScoped<IGetUsersService, GetUsersService>(); تعریف: این خط به DI Container می‌گوید که هر بار که نیاز به IGetUsersService وجود دارد، یک نمونه از GetUsersService ایجاد کند. و Scope: همانند IDataBaseContext، Scoped به این معنی است که یک نمونه جدید برای هر درخواست HTTP ساخته می‌شود. AddScoped<IGetRolesService, GetRolesService>(); تعریف: این خط به DI Container می‌گوید که هر بار که نیاز به IGetRolesService وجود دارد، یک نمونه از GetRolesService ایجاد کند. و Scope: باز هم، Scoped به این معنی است که یک نمونه جدید برای هر درخواست HTTP ساخته می‌شود. نتیجه‌گیری این خطوط کد سه سرویس مختلف را به DI Container اضافه می‌کنند و به برنامه شما اجازه می‌دهند تا وابستگی‌ها را به طور خودکار تزریق کند. هر سرویس با استفاده از الگوی Scoped ایجاد می‌شود، به این معنی که یک نمونه جدید برای هر درخواست HTTP ایجاد می‌شود.
EndPoint.Site => Areas => Admin => Controllers => UsersController.cs نام‌فضا (Namespace) csharp namespace EndPoint.Site.Areas.Admin.Controllers این خط، نام‌فضا (namespace) EndPoint.Site.Areas.Admin.Controllers را تعریف می‌کند. نام‌فضاها برای سازماندهی و دسته‌بندی کدها استفاده می‌شوند. استفاده از Area csharp [Area("Admin")] این خط کنترلر را به یک ناحیه (Area) به نام Admin اختصاص می‌دهد. Areas در ASP.NET Core برای تقسیم‌بندی منطق برنامه به بخش‌های جداگانه استفاده می‌شود. تعریف کلاس UsersController csharp public class UsersController : Controller این خط کلاس UsersController را تعریف می‌کند که از کلاس پایه Controller ارث‌بری می‌کند. متغیرهای خصوصی و سازنده csharp private readonly IGetUsersService _getUsersService; private readonly IGetRolesService _getRolesService; public UsersController(IGetUsersService getUsersService, IGetRolesService getRolesService) { _getUsersService = getUsersService; _getRolesService = getRolesService; } متغیرهای خصوصی: دو متغیر خصوصی از نوع اینترفیس‌های IGetUsersService و IGetRolesService تعریف می‌شوند که برای دریافت کاربران و نقش‌ها استفاده می‌شوند. سازنده: سازنده UsersController دو پارامتر از نوع اینترفیس‌های ذکر شده را دریافت کرده و آن‌ها را به متغیرهای خصوصی اختصاص می‌دهد. این پارامترها از طریق DI (Dependency Injection) تزریق می‌شوند. متد Index csharp public IActionResult Index(string serchKey, int page = 1) { return View(_getUsersService.Execute(new RequestGetUserDto { Page = page, SearchKey = serchKey, })); } public IActionResult Index(string serchKey, int page = 1): این متد برای نمایش صفحه اصلی کاربران استفاده می‌شود. پارامترهای serchKey و page برای جستجو و صفحه‌بندی استفاده می‌شوند. بازگشت View: این متد نتیجه اجرای متد Execute از سرویس IGetUsersService را به ویو بازمی‌گرداند. این نتیجه شامل لیستی از کاربران و تعداد کل کاربران است. متد Create csharp [HttpGet] public IActionResult Create() { ViewBag.Roles = new SelectList(_getRolesService.Execute().Data, "Id", "Name"); return View(); } [HttpGet]: این اتریبیوت نشان می‌دهد که این متد فقط برای درخواست‌های GET مورد استفاده قرار می‌گیرد. public IActionResult Create(): این متد برای نمایش فرم ایجاد کاربر جدید استفاده می‌شود. ViewBag.Roles: این خط نقش‌ها را از سرویس IGetRolesService دریافت کرده و آن‌ها را در ViewBag ذخیره می‌کند تا در ویو به صورت لیست کشویی نمایش داده شوند. بازگشت View: این متد ویو Create را نمایش می‌دهد که شامل فرم ایجاد کاربر جدید است. نتیجه‌گیری این کنترلر UsersController برای مدیریت کاربران در ناحیه Admin استفاده می‌شود. شامل دو متد اصلی است: Index: برای نمایش لیست کاربران با قابلیت جستجو و صفحه‌بندی. Create: برای نمایش فرم ایجاد کاربر جدید و دریافت نقش‌ها از دیتابیس و نمایش آن‌ها به صورت لیست کشویی. این ساختار کنترلر به شما امکان می‌دهد تا کاربران و نقش‌ها را به صورت کارآمد مدیریت کنید و از DI برای تزریق وابستگی‌ها استفاده کنید.
در packing manager console عبارت Add-Migration AddRoles و بعد Update-Database وارد کنید
Test_Store 6.zip
حجم: 45.7M
قسمت آخر user ثبت نام و ورود واقعا ببخشید که کد های من زمان زیادی طول کشید بعدا کد ها را توضیح می دهم
ساختار درختی پوشه و فایل Test_Store │ ├── Doc │ ├── Src │ ├── Common │ │ └── library: Test_Store.Common │ │ ├── Dto │ │ │ └── ResultDto.cs │ │ ├── Roles │ │ │ └── UserRoles.cs │ │ ├── Pagination.cs │ │ └── PasswordHasher.cs │ │ │ ├──── Core │ │ ├──── library: Test_Store.Application │ │ │ ├── Interfaces │ │ │ │ ├── Contexs │ │ │ │ │ └── IDataBaseCotex.cs │ │ │ │ └── FacadPatterns │ │ │ │ └── IProductFacad.cs │ │ │ └── Services │ │ │ ├── Users │ │ │ │ ├── Commands │ │ │ │ │ ├── EditUser │ │ │ │ │ │ └── IEditUserService.cs │ │ │ │ │ ├── RegisterUser │ │ │ │ │ │ └── IRegisterUserService.cs │ │ │ │ │ ├── RemoveUser │ │ │ │ │ │ ├── IRemoveUserService.cs │ │ │ │ │ │ └── RemoveUserService.cs │ │ │ │ │ ├── UserLogin │ │ │ │ │ │ └── IUserLoginService.cs │ │ │ │ │ └── UserSatusChange │ │ │ │ │ └── IUserSatusChangeService.cs │ │ │ │ └── Queries │ │ │ │ ├── GetRoles │ │ │ │ │ ├── GetRolesService.cs │ │ │ │ │ ├── IGetRolesService.cs │ │ │ │ │ └── RolesDto.cs │ │ │ │ └── GetUsers │ │ │ │ ├── GetUsersDto.cs │ │ │ │ ├── GetUsersService.cs │ │ │ │ ├── IGetUsersService.cs │ │ │ │ ├── RequestGetUserDto.cs │ │ │ │ └── ReslutGetUserDto.cs │ │ │ └── Products │ │ │ ├── Commands │ │ │ │ └── AddNewCategory │ │ │ │ └── IAddNewCategoryService.cs │ │ │ ├── FacadPattern │ │ │ │ └── ProductFacad.cs │ │ │ └── Queries │ │ │ └── GetCategories │ │ │ └── IGetCategoriesService.cs │ │ │ │ │ └── library: Test_Store.Domain │ │ └── Entities │ │ ├── Users │ │ │ ├── Role.cs │ │ │ ├── User.cs │ │ │ └── UserInRole.cs │ │ ├── Commons │ │ │ ├── BaseEntity.cs │ │ │ └── BaseEntityNotId.cs │ │ └── Products │ │ └── Category.cs │ │ │ ├── Infrastructure │ │ ├── library: Test_Store.Infrastructure │ │ └── library: Test_Store.Persistence │ │ ├── Context │ │ │ └── DataBaseContext.cs │ │ └── Migrations │ │ ├── ......_Users.cs │ │ └── DataBaseContextModelSnapshot.cs │ │ │ └── Presentation │ └── ASP.NET Core: EndPoint.Site │ │ │ ├── Areas │ │ └── Admin │ │ ├── Controllers │ │ │ └── UsersController.cs │ │ ├── Views │ │ │ ├── Shared │ │ │ │ └── _AdminLayout.cshtml │ │ │ └── Users │ │ │ ├── Create.cshtml │ │ │ └── Index.cshtml │ │ └── Models │ ├── Controllers │ │ ├── AuthenticationController.cs │ │ └── HomeController.cs │ ├── Views │ │ ├── Authentication │ │ │ ├── Signin.cshtml │ │ │ └── Signup.cshtml │ │ ├── Home │ │ │ ├── Index.cshtml │ │ │ └── Privacy.cshtml │ │ ├── Shared │ │ │ ├── _Layout.cshtml │ │ │ ├── _ValidationScriptsPartial.cshtml │ │ │ └── Error.cshtml │ │ ├── _ViewImports.cshtml │ │ └── _ViewStart.cshtml │ ├── Models │ │ ├── ViewModels │ │ │ └── AuthenticationViewModel