今天要來實作 Details 詳細資料頁面
ViewModel 是拿來對 MVC 一個 View 只能對應一個 Model 的概念
所做出的因應對策,其實就是把需要用到的 Model 跟資料再用一個更大 Model 包起來,就成了所謂的 ViewModel。就如同名字 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。
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.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>
最後排版一下看看成果如何