iT邦幫忙

2025 iThome 鐵人賽

DAY 10
0
佛心分享-SideProject30

30天的旅程!從學習C#到開發小專案系列 第 10

DAY 10 - 認識傳輸資料小幫手DTO (資料傳輸物件)

  • 分享至 

  • xImage
  •  

哈囉大家好!
昨天介紹完如何利用Model定義資料表的欄位和使用migration對資料表進行新增和修改後,
今天要來介紹幫助我們優化資料傳輸過程的工具-DTO!

什麼是DTO?

在C# MVC(Model-View-Controller)架構中,DTO(Data Transfer Object), 又稱為「資料傳輸物件」,是一個簡單的C# Class,主要用來在應用程式的不同層(如:控制器、服務層、資料存取層)間傳遞資料。

DTO可以視為一種設計模式,通常只包含Properties,不會在DTO Class中撰寫業務邏輯或行為方法。透過DTO可以將不同層的資料格式進行標準化和封裝,進而提高資料傳輸的效率。
我們也可以在DTO Class中設定可以檢視的欄位!假設我不想要讓使用者看到上傳貼文的點讚數,我就可以建立一個PostDTO, 只包含作者、標題、內容...等property(欄位),接著就可以在Controller中使用PostDTO來傳輸資料給前端。

感覺DTO超級完美的~但其實在使用上也有一些小缺點,下方來比較一下使用DTO的優缺點:

優點

  1. 資訊隱藏!避免暴露敏感資料(例如:密碼、使用者資料...等)到前端
  2. 解耦(Decoupling),因為DTO把Controller和資料模型(ORM Model)解耦,當需要調整資料庫模型時,只需要調整service和DTO, Controller和前端部分不太需要再出新條整,讓程式碼更容易維護。
  3. 因為只需要傳輸需要的資料,所以能提高傳輸效能,減少網路傳輸的資料量。
  4. DTO支援針對性的資料驗證規則,例如:資料註解[Required]來指定對應欄位為必填。

缺點

  1. 開發者可能會混淆Model和DTO的使用
  2. 需要為每個傳輸的情境建立新的DTO,程式碼量增加

總結來說,在開發小型專案且資料結構不需要經常變動的情況時,不使用DTO可能是更快速簡單的方法。相反地,若開發大型且較複雜的專案,需要有一定擴展性的應用程式,還是會偏向選擇DTO來輔助。

簡單介紹完DTO後,要來試試如何透過程式碼實現更有效能的資料傳輸~

首先先看一眼昨天定義的Post Model:(新增點讚數LikeAmount欄位)

namespace ExampleApp.Models
{
    public class Post
    {
        public int Id { get; set; }
        public int UserId { get; set; }
        public string? Title { get; set; }
        public string? Body { get; set; }
        public int LikeAmount { get; set; } 
    }
}

接著可以建立一個DTO資料夾,裡面專門放DTO Class。
這裡建立一個PostDTO: (只設定我想要傳輸的property)

namespace ExampleApp.DTOs
{
    public class PostDTO
    {
        public int Id { get; set; }
        public int UserId { get; set; }
        public string? Title { get; set; }
        public string? Body { get; set; }
    }
}

接著建立一個專門處理Post行為的service:

using ExampleApp.Models;
using ExampleApp.DTOs; 

public class PostService
{
    // 假設我們從某個地方(例如資料庫或外部 API)獲取 Post 資料
    // 這個方法的回傳型別是 PostDTO,代表它只會傳輸精簡過的資料
    public PostDTO GetPost(int userId)
    {
        // 模擬從資料庫讀取一個完整的 Post 實體(Entity)
        // 這個物件包含了所有資料庫欄位,包括敏感或不需傳輸的資訊
        var postEntity = new Post
        {
            Id = 1, // 假設 ID 是 1
            UserId = userId,
            Title = "iThome 鐵人賽挑戰第10天!",
            Body = "這是一篇關於C# DTO的分享文章。",
            LikeAmount = 100 // 這個欄位是我們不打算傳輸給前端的
        };
        
        // 進行資料轉換(Data Mapping)
        // 將 postEntity 的部分資料,複製到 postDto 中
        var postDto = new PostDTO
        {
            Id = postEntity.Id,
            UserId = postEntity.UserId,
            Title = postEntity.Title,
            Body = postEntity.Body
            // 注意:這裡沒有將 postEntity.LikeAmount 複製過來
        };
        
        // 返回 DTO 物件,將其傳輸給呼叫者(例如 Controller 或其他service)
        return postDto;
    }
}

簡單介紹了DTO,其使用上的優缺點和程式碼實際範例,明天要來認識套件管理工具-NuGet!


上一篇
DAY 9 - 使用 Model 定義資料結構與 Migration 編輯資料庫
下一篇
DAY 11 - 認識套件管理工具 - NuGet!
系列文
30天的旅程!從學習C#到開發小專案12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言