iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0

今天首先要講的是單一Model(不參雜其他Model),設置資料表與頁面。
步驟適用於各種單一Model,以建立類別為案例:

  • 建立Category步驟

1.建立Model
2.設置DbContext:在Context內定義Model與預設資料
2.1Add-migration 建立資料表
2.2Add-migration 寫入預設資料
3.建立Repository、IRepository。
4.修改UnitOfWOrk、IUnitOfWork。
5.Area區域新增資料:View與Controller(CRUD)的設置
6._Layout修正:設置類別連結。

  • 建立類別MODEL

專案Model=>右鍵=>新增項目=>Category.cs

public class Category
    {
        [Key]
        public int Id { get; set; }
        [Required]
        [MaxLength(30)]
        [DisplayName("類別名稱")]
        public string Name { get; set; }
        [DisplayName("顯示順序")]
        [Range(1, 100, ErrorMessage = "輸入範圍應該要在1-100之間")]
        public int DisplayOrder { get; set; }
    }

1.設置Id為主鍵
2.設置類別名稱,限制最常30字元。
3.設置顯示順序,限制1-100之間。

  • 設置DbContext
    打開Data專案=>ApplicationDbContext.cs新增Model與預設資料。
    https://ithelp.ithome.com.tw/upload/images/20240915/20147438rvdKj66kl2.jpg
public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
        {
        }
        public DbSet<Category> Categories { get; set; }
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Category>().HasData(
new Category { Id = 1, Name = "上衣", DisplayOrder = 1 },
new Category { Id = 2, Name = "洋裝", DisplayOrder = 2 },
new Category { Id = 3, Name = "下半身", DisplayOrder = 3 }
);
}
}

工具=>NuGet套件管理員=>套件管理器主控台=>預設專案DataAccess
Add-migration AddCategoryTbl:根據Model預產出Categories資料表的程式碼。
執行update-database:根據Migration在DB產生資料表。

  • 備註:Migration修正
    add-migration,update-database前,發現有錯誤,想重新產生可以先remove-migration。
    修正Model或資料,再重新add-migration。
    如果已經是前幾個migration發現有問題,可以先add-migration,然後複製有問題的做修改貼上。重新add與update-database。

https://ithelp.ithome.com.tw/upload/images/20240915/20147438JW7UbU0kav.jpg

  • 建立UnitOfWork
public ICategoryRepository Category { get; private set; }
Category = new CategoryRepository(_db);

_db=db;
一定要在Category上面,不然會讀不了資料。
https://ithelp.ithome.com.tw/upload/images/20240915/20147438DBm5A4UkEy.jpg

  • 建立IUnitOfWork
 ICategoryRepository Category { get; }

https://ithelp.ithome.com.tw/upload/images/20240915/20147438bP7jIiEi0V.jpg

  • 建立CRUD
    Controller右鍵=>加入=>控制器=>使用Entity FrameWork執行
    建立CategoryController,View資料夾自動產出CRUD
    此處簡單介紹一般架構下,快速產生預設檔案。[後面大多用不到]。
    CategoryController.cs
    https://ithelp.ithome.com.tw/upload/images/20240915/20147438VEL1o6LVaG.jpg

Create與Edit後面會合併成一個頁面
=>Edit與Detail可以直接刪除。
share_Lyout.cshtml,增加類別功能。
Category屬於Admin區。
https://ithelp.ithome.com.tw/upload/images/20240915/20147438FquJuefBuE.jpg

  • 修改CategoryController
    1.IUnitOfWork是一個介面,用於對Category資料操作。
    readonly修飾該介面的私有欄位_unitOfWork,讓這欄位不會被Controller其他方法任意更改。
    將IUnitOfWork實作物件注入到控制器的建構函式中,使用Category物件的資料存取功能。
    2.新增[Area("Admin")]
    3.ActionResult Index()修改:
    使用_unitOfWork調出Category的GetAll()。
    https://ithelp.ithome.com.tw/upload/images/20240915/20147438f7J4xS05ai.jpg
 private readonly IUnitOfWork _unitOfWork;

        public CategoryController(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }
 public IActionResult Index()
        {
            List<Category> objCategoryList = _unitOfWork.Category.GetAll().ToList();
            return View(objCategoryList);
        }
  • ActionResult Upsert ()修改:
    https://ithelp.ithome.com.tw/upload/images/20240915/20147438rvO8MZtwoI.jpg
 public IActionResult Upsert(int? id)
        {

            if (id == null || id == 0)
            {
                return View(new Category());
            }
            else
            {
                Category categoryObj = _unitOfWork.Category.Get(u => u.Id == id);
                return View(categoryObj);
            }
        }

https://ithelp.ithome.com.tw/upload/images/20240915/201474380cCCMbWSLg.jpg

[HttpPost]
       public IActionResult Upsert(Category categoryObj)
       {
           if (categoryObj.Name == categoryObj.DisplayOrder.ToString())
           {
               ModelState.AddModelError("name", "類別名稱不能與顯示順序一致");
           }
           if (ModelState.IsValid)
           {
               if (categoryObj.Id == 0)
               {
                   _unitOfWork.Category.Add(categoryObj);
                   TempData["success"] = "類別新增成功!";
               }
               else
               {
                   _unitOfWork.Category.Update(categoryObj);
                   TempData["success"] = "類別更新成功!";
               }
               _unitOfWork.Save();
               return RedirectToAction("Index");
           }
           return View(categoryObj);
       }
  • ActionResult Delete()修改。
    只要保留HttpPost的就好,return Delete View的程式碼移除。

https://ithelp.ithome.com.tw/upload/images/20240915/20147438eef7PR4xWw.jpg

 [HttpPost]
        public IActionResult Delete(int id)
        {
            Category? obj = _unitOfWork.Category.Get(u => u.Id == id);
            if (obj == null)
            {
                return NotFound();
            }
            _unitOfWork.Category.Remove(obj);
            _unitOfWork.Save();
            return RedirectToAction(nameof(Index));
        }
  • 修改Index View

https://ithelp.ithome.com.tw/upload/images/20240915/20147438mrJuCqvtHc.jpg

@model IEnumerable<ClothesMall.Models.Category>
<p>
    <a asp-action="Upsert" class="btn btn-success">
        <i class="bi bi-plus-circle"></i>Create New</a>
</p>
<table  id="categoryTbl"  class="table">
    <thead>
        <tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.DisplayOrder)
</th>
<th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.DisplayOrder)
</td>
<td>
<a asp-action="Upsert" asp-route-id="@item.Id" class="btn btn-primary mx-2">
<i class="bi bi-pencil-square"></i>Edit</a> |
 <button type="button" class="btn btn-danger mx-2 delete-btn" data-id="@item.Id">Delete</button>
</td>
        </tr>
}
    </tbody>
</table>
  • 修改Delete功能

https://ithelp.ithome.com.tw/upload/images/20240915/2014743881ZYRQalBT.jpg

@section Scripts {
    <script>
        $(document).ready(function () {
            $(".delete-btn").click(function () {
                var id = $(this).data("id");
                if (confirm("Are you sure you want to delete this category?")) {
                    $.ajax({
                        url: "@Url.Action("Delete", "Category")",
                        type: "POST",
                        data: { id: id },
                        success: function () {
                            location.reload();
                        }
                    });
                }
            });
        });
    </script>
}
  • _Layout修正

增加下拉選單:類別已被放置Admin區域,新增內容管理在導覽列。
後續與Admin相關的都會被放入“內容管理”
開啟Shared/_Layout.cshtml,找到nav-item會發現asp-area="",已經建立完畢,將asp-area加上區域名稱。

https://ithelp.ithome.com.tw/upload/images/20240915/20147438Nh8eei7dqT.jpg

 <li class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-dark" data-bs-toggle="dropdown" href="#" 
role="button" aria-haspopup="true" aria-expanded="false">內容管理</a>
<div class="dropdown-menu">
<a class="dropdown-item" asp-area="Admin" asp-controller="Category" asp-action="Index">類別</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" asp-area="Identity" asp-page="/Account/Register">建立使用者</a>
</div>
</li>

修改完後就可以開啟類別頁面了


上一篇
Day12 分層架構設置
下一篇
Day14 新增產品頁面
系列文
asp.net core 分層架構快速上手31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言