iT邦幫忙

2021 iThome 鐵人賽

DAY 11
0
Modern Web

從實作學習ASP.NET Core - 30天的購物網站系列 第 11

【從實作學習ASP.NET Core】Day11 | 後台 | 詳細資料與 ViewModel

今天要來實作 Details 詳細資料頁面


ViewModel

ViewModel 是拿來對 MVC 一個 View 只能對應一個 Model 的概念 所做出的因應對策,其實就是把需要用到的 Model 跟資料再用一個更大 Model 包起來,就成了所謂的 ViewModel。就如同名字 ViewModel 只應該拿來顯示資料用,不要直接拿來對資料庫操作。

建立 Details 的 ViewModel

在 Model 的資料夾新增一個 DetailViewModel.cs

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

namespace OnlineShopCMS.Models
{
    public class DetailViewModel
    {
        public Product product { get; set; }
        public string imgsrc { get; set; }
    }
}

簡單的顯示也可以直接用 ViewData ViewBag 來實現就好,ViewModel 通常是前端畫面需要多個模型的時候使用。今天的例子主要是想要拿來示範,實際在操作的時候不見得需要用到 ViewModel。

Details 的 Action

ProductsController.cs

public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }
    
    DetailViewModel dvm = new DetailViewModel();  //建立一個 ViewModel
    
    var product = await _context.Product
                .Include(p => p.Category)
                .FirstOrDefaultAsync(m => m.Id == id);
    if (product == null)
    {
        return NotFound();
    }
    else
    {
        dvm.product = product;
        if (product.Image != null)
        {
            dvm.imgsrc = ViewImage(product.Image);
        }
    }
    return View(dvm); //回傳 ViewModel
}
private string ViewImage(byte[] arrayImage) 
{
    // 二進位圖檔轉字串
    string base64String = Convert.ToBase64String(arrayImage, 0, arrayImage.Length);
    return "data:image/png;base64," + base64String;
}

Details 的 View 頁面

前端 Details.cshtml 改為 @DetailViewModel 模型來接

@model OnlineShopCMS.Models.DetailViewModel

@{
    ViewData["Title"] = "Details";
}

<h1>Details</h1>

<div>
    <h4>Product</h4>
    <hr />
    <dl class="row">
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.Image)
        </dt>
        <dd class = "col-sm-10">
            <img src="@Html.DisplayFor(model => model.imgsrc)" />    //圖片
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.product.Name)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.product.Name)            //名稱
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.product.Description)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.product.Description)      //簡介
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.product.Price)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.product.Price)            //價格
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.product.Stock)
        </dt>
        <dd class = "col-sm-10">
            @Html.DisplayFor(model => model.product.Stock)            //庫存
        </dd>
        <dt class = "col-sm-2">
            @Html.DisplayNameFor(model => model.product.Content)
        </dt>
        <dd class = "col-sm-10">
            @Html.Raw(Model.product.Content)                          //內容
        </dd>
    </dl>
</div>
<div>
    <a asp-action="Edit" asp-route-id="@Model.Id">Edit</a> |
    <a asp-action="Index">Back to List</a>
</div>

最後排版一下看看成果如何


上一篇
【從實作學習ASP.NET Core】Day10 | 後台 | 文字編輯器 CKEditor
下一篇
【從實作學習ASP.NET Core】Day12 | 後台 | 資料篩選與分頁
系列文
從實作學習ASP.NET Core - 30天的購物網站30

尚未有邦友留言

立即登入留言