設計ASP.NET MVC4應用程式(1)

by vivid 5. 十二月 2012 01:23

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:N121213101
出刊日期:2012/12/05

Visual Studio 2012內建ASP.NET MVC 4版本,您可以直接利用它來建立ASP.NET MVC 4專案,撰寫網站程式碼。本文將介紹ASP.NET MVC 4網站設計的第一步,讓您能夠利用MVC模式以及Visual Studio 2012的範本來了解ASP.NET MVC 4網站設計的基本概念。

MVC是一個軟體工程中常用到的設計模式,參考圖1所示,代表Model-View-Controller:

  • Model:Model包含封裝的資料以及資料的處理邏輯,包含商業邏輯、驗證邏輯或資料存取類別與邏輯。處理邏輯和操作邏輯是分開的,操作邏輯是透過Controller來控管。而View是負責展示的邏輯。
  • View:使用者介面部分,包含HTML標記、Scripts程式碼。View參考Model,使用Model提供的唯讀的方法來查詢以及取回資料。在ASP.NET MVC應用程式中,View會以HTML標籤的方式呈現。
  • Controller:Controller物件負責連接Model與View兩者。控制使用者互動,與操作流程。

clip_image002[4]

圖 1:MVC模式

要學習ASP.NET MVC4 最快的就是動手來寫個程式吧,從Visual Studio 2012開發工具 -「檔案」-「新增」-「專案」,在「新增專案」對話盒中選取程式語言,例如本範例選擇「Visual C#」,從「Web」分類中,選取「ASP.NET MVC 4 Web應用程式」,名稱部分使用預設的名稱;按下「確定」鍵,請參考下圖所示:

clip_image004[4]

圖 2:建立ASP.NET MVC 4 Web應用程式。

在建立「ASP.NET MVC 4 Web應用程式」步驟後,會出現一個「新ASP.NET MVC 4專案」對話盒,裡頭有許多不同類型的MVC專案範本,並選用不同的檢視引擎來設計程式,這些預設的範本包含:

  • 空白:含有基本網站應用程式的骨架,包含MVC所需的目錄,如Controllers、Models、Views。,以及一些基本公用程式碼,如打包與壓縮JavaScript所需的類別。
  • 基本:含有基本網站應用程式的骨架,包含MVC所需的目錄,如Controllers、Models、Views,以及一些基本公用程式碼,如打包與壓縮JavaScript所需的類別,CSS樣式表。除此之外,也包含一些基本的JavaScript Framework函式庫,例如jquery-1.7.1.js、jquery-ui-1.8.20.js、jquery.validate.js…等等。
  • 網際網路應用程式:設計以MVC為基礎的網站範本,並提供一些基本網頁、CSS樣式表、圖片檔與程式碼,例如整合ASP.NET會員服務(Membership Service)的帳號管理程式碼,以表單方式進行驗證。
  • 內部網路應用程式:用來設計內部網站應用程式,和「網際網路應用程式」雷同,但帳號部分採用Windows驗證。
  • 行動應用程式:主要是用來設計整合jQuery Mobile Framework的網站應用程式,提供了一些基本網頁、CSS樣式表、包含jquery-1.7.1.js、jquery.mobile-1.1.0.js函式庫…等等。
  • Web API:ASP.NET Web API架構內含在ASP.NET 4.5,主要是應用在設計HTTP服務,可以建立一個 HTTP 服務讓多種用戶端存取,例如一般桌上型電腦的瀏覽器或行動裝置。ASP.NET Web API 能透過.NET Framework 建置支援 RESTful架構的應用程式。

我們在這個步驟選取「網際網路應用程式」,請參考下圖所示:

clip_image006[4]

圖 3:「新ASP.NET MVC 4專案」對話盒。

「新ASP.NET MVC 4專案」對話盒中間區塊可以選擇想要使用的檢視引擎(View Engine)。檢視引擎有兩種,以不一樣的方式來產生HTML標籤。Razor是MVC3版之後新增的檢視引擎,利用Razor語法建立檢視(View),請參考下圖所示:

clip_image007[4]

圖 4:檢視引擎有兩種。

「新ASP.NET MVC 4專案」對話盒的下方區塊可以選擇要不要為你的MVC應用程式建立單元測試專案,預設使用Visual Studio Unit Test 測試架構。本文不探討測試專案,先跳過此步驟。

MVC專案結構

當你建立一個ASP.NET MVC 4應用程式專案後,Visual Studio 2012會自動在專案中建立許多目錄以及各式各種類型的檔案到專案之中,請參考下圖所示:

clip_image008[4]

圖 5:ASP.NET MVC 4應用程式專案目錄結構。

這些目錄包含:

  • App_Data:存放資料庫檔案。
  • App_Start:用來置放路由(RouteConfig.cs)、打包腳本程式(BundleConfig.cs)、篩選(FilterConfig.cs)、驗證(AuthConfig.cs)、Web API(WebApiConfig.cs) 等組態設定程式。
  • Content:置放CSS樣式表及樣式表使用的圖片檔。
  • Controllers:用來存放控制器類別程式碼。預設包含AccountController.cs、HomeController.cs檔案。
  • Filters:存放篩選程式。
  • Images:存放網站要顯示的圖片檔案。
  • Models:用來存放操作資料的模型(Model)類別程式碼。
  • Scripts:網站應用程式使用到的JavaScript檔案。
  • Views:存放呈現使用者介面的檢視表檔案。此目錄下方,預設有Account、Home、Shared等三個子目錄,目錄中都置放了一些範本網頁檔(*.cshtml)。

在Visual Studio 2012開發工具按F5執行這個應用程式,Visual Studio 2012預設會使用IIS Express來執行你的網站應用程式。自動賦予此網站一個埠號來執行,此筆者目前的環境而言,網站路徑為「http://localhost:44913」,代表使用44913埠。網站應用程式執行後會啟動瀏覽器,首先映入眼簾的就是網站中的首頁,請參考下圖所示:

clip_image010[4]

圖 6:網站首頁(Home)。

點選畫面中上方的「關於」選單,可以看到以下頁面,請參考下圖所示:

clip_image012[4]

圖 7:網站關於頁面(About)。

點選畫面中上方的「連絡」選單,可以看到以下頁面,請參考下圖所示:

clip_image014[4]

圖 8:網站連絡頁面(Contact)。

點選畫面中上方的「登入」選單,可以看到以下頁面,請參考下圖所示:

clip_image016[4]

圖 9:網站登入頁面(Login)。

點選畫面中上方的「註冊」選單,可以看到以下頁面,請參考下圖所示:

clip_image017[4]

圖 10:網站註冊頁面(Register)。

 

設計Controller

在MVC模式中,Controller主要負責接收使用者的輸入資料,連接Model與View兩者,控制使用者互動,與操作流程。當你建立一個ASP.NET MVC 4應用程式專案後,在專案Controllers目錄下便有一個HomeController.cs檔案,其中定義了一個簡單的HomeController:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Controllers {
  public class HomeController : Controller {
    public ActionResult Index ( ) {
      ViewBag.Message = "修改此範本即可開始著手進行您的 ASP.NET MVC 應用程式。";
      return View ( );
    }

    public ActionResult About ( ) {
      ViewBag.Message = "您的應用程式描述頁面。";
      return View ( );
    }

    public ActionResult Contact ( ) {
      ViewBag.Message = "您的連絡頁面。";
      return View ( );
    }
  }
}

HomeController繼承自Controller類別,其中包含三個方法:Index、About、Contact。Index方法用來處理使用者想存取網站首頁的請求。依此類推About方法用來處理「關於」的請求;About方法用來處理「連絡」的請求。

讓我們稍微修改一下程式碼,修改Index方法中指定給ViewBag.Message的字串為:「我的第一個 ASP.NET MVC 4 應用程式!」:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Controllers {
  public class HomeController : Controller {
    public ActionResult Index ( ) {
      ViewBag.Message = "我的第一個 ASP.NET MVC 4 應用程式!";

      return View ( );
    }

    public ActionResult About ( ) {
      ViewBag.Message = "您的應用程式描述頁面。";

      return View ( );
    }

    public ActionResult Contact( ) {
      ViewBag.Message = "您的連絡頁面。";

      return View ( );
    }
  }
}

 

在Visual Studio 2012按F5執行這個應用程式,您可以看到首頁上方顯示了「我的第一個 ASP.NET MVC 4 應用程式!」這個字串,請參考下圖所示:

clip_image019[4]

圖 11:顯示自訂訊息。

您可以檢視Views\Home\Index.cshtml檔案中,使用了「@ViewBag.Message」Razor陳述式語法來顯示自訂的訊息:

 

<hgroup class = "title" >

<h1> @ViewBag.Title. </h1>

<h2> @ViewBag.Message </h2>

</hgroup>

 

撰寫控制器(Controller)

我們也可以從無到有,自行撰寫控制器(Controller)來處理HTTP請求。從Visual Studio 2012開發工具-「方案總管」-你的專案-「Controllers」目錄上方按滑鼠右鍵,從快捷選單選擇「加入」-「控制器」,請參考下圖所示:

clip_image021[4]

圖 12:新增控制器。

在「加入控制器」對話盒中,將控制器名稱設定為「EmployeeController」,範本選擇「空白MVC控制器」,然後按下「加入」按鈕,請參考下圖所示:

clip_image022[4]

圖 13:建立EmployeeController控制器。

Visual Studio 2012會自動建立一個繼承自Controller 類別的EmployeeController類別,預設其中包含一個Index方法。控制器中的方法稱為action。修改EmployeeController控制器Index action程式碼,讓此方法回傳字串型別;回傳的字串為「執行EmployeeController Index action」:

 

namespace MvcApplication1.Controllers {
  public class EmployeeController : Controller {
    //
    // GET: /Employee/
    public string Index ( ) {
      return "執行EmployeeController Index action" ;
    }
  }
}

 

最基本的Controller程式碼已經完成,雖然還沒有設計檢視(View)或是模型(Model),不過無妨,控制器仍可以執行,接收使用者HTTP請求,並將結果呈現在網頁上。您可以直接按F5來執行。只要在瀏覽器上輸入以下URL:

http://localhost:44913/Employee

或輸入以下URI:

http://localhost:44913/Employee/Index

都會得到相同的執行結果,請參考下圖所示:

clip_image024[4]

圖 14:EmployeeController Index action執行結果。

 

使用參數

Action可以接收參數,參數值是來自於HTTP請求URL後的查詢字串。例如為EmployeeController加入一個Details action,傳入一個id參數,回傳一個字串:

public string Details ( int id ) {
  return "執行EmployeeController Index action! ID參數 = " + id ;
}

 

按F5來執行程式,在瀏覽器上輸入以下兩種URL語法:

http://localhost:44913/Employee/Details?id=100

http://localhost:44913/Employee/Details/100

都可以得到相同的執行結果,請參考下圖所示:

clip_image026[4]

圖 15:EmployeeController Details action執行結果。

你可以利用查詢字串傳遞參數到Details action(如上述第一個URL),或利用MVC的路由機制(如上述第二個URL)來正確執行Details action。

 

設計檢視(View)

在許多的網頁程式中,要展現的使用者介面可能相當地複雜,不是單純像前述的範例,利用控制器(Controller)回傳字串顯示在瀏覽器上那麼的單純。我們可以利用檢視(View)來定義呈現在展示層的HTML標籤,也就是說利用檢視來定義使用者介面。

修改EmployeeController的Index action,利用Controller類別的View方法讓它回傳一個名叫Index的檢視,Index action中將「執行EmployeeController Index action」字傳放到ViewBag的Message屬性之中,我們可以利用ViewBag從Controller傳遞資料到View:

namespace MvcApplication1.Controllers {
  public class EmployeeController : Controller {
   
  public ActionResult Index ( ) {
    ViewBag.Message = "執行EmployeeController Index action" ;
      return  View ( "Index" );
    }
   
  }
}

ViewBag是一個支援dynamic技術的字典(Dictionary)類型物件。語法比起MVC2之前使用的ViewData物件更為精簡。

接下來您可以將滑鼠停留在Index action程式碼上方,按滑鼠右鍵,從快捷選單選取「加入檢視」,請參考下圖所示:

clip_image027[4]

圖 16:加入檢視。

隨即出現「加入檢視」對話盒,您可以設定以下資料:

  • 檢視名稱:設定檢視名稱,預設名稱會根據action的名稱產生。
  • 檢視引擎:ASP.NET MVC 3版本之前,只有ASPX這種檢視引擎,自ASP.NET MVC 3版本之後,檢視引擎就分為兩種:ASPX與Razor。
  • 建立強型別檢視:啟用後可以選擇要從Controller傳遞到View的資料模型類別。
  • Scaffold樣版:可以根據模型自動產生資料編修的檢視頁面。包含:Empty、Create、Delete、Details、Edit、List等等。
  • 參考指令碼程式庫:若勾選此項目,某些Scaffold樣版,例如Edit、Create產生的頁面,會額外加入引用jquery.validate.unobtrusive與jquery.validate函式庫的程式區塊。
  • 建立成部分檢視:建立出的View不是完整的View。
  • 使用配置或主版頁面:檢視是否參照Layout檔案或主版頁面建立。

在此步驟先設定名稱為「Index」,按下「加入」按鈕,請參考下圖所示:

clip_image028[4]

圖 17:加入檢視。

完成這個步驟之後,專案中「Views」下就會出現一個「Employee」子目錄,裏頭有一個Index.cshtml,請參考下圖所示:

clip_image029[4]

圖 18:加入檢視。

根據ASP.NET MVC的規則,Views下的子目錄,是根據Controller的名稱來命名(去掉Controller字眼)。因此控制項名稱叫EmployeeController;對應的Views子目錄名稱就為「Employee」。檢視的檔名則是根據action來命名。因為所選的程式語言為C#,所以Action的名稱為Index,因此檔名為Index.cshtml。若選用Visual Basic程式語言建立MVC專案,則檔名就會是Index.vbhtml。

Razor檢視引擎是預設的檢視引擎,是一個輕量級、語法更為簡潔的檢視引擎,通常以@符號開始。語法分為兩種陳述式(Expression) 與程式區塊(Code Block)。我們來修改一下這個Index.cshtml,在程式最下方,加入程式碼,印出ViewBag.Message的值:

@{
    ViewBag.Title = "Index" ;
}
<h2> Index </h2>
<p> @ViewBag.Message </p>

 

@ViewBag.Message即為陳述式。前三行則是程式區塊(Code Block) 語法。

和一般的ASP.NET Web Forms網頁不太一樣,您無法直接從URL存取這個Index.cshtml檔案;View將會由Controller 來建立。EmployeeController的Index action,叫用Controller類別的View方法,傳入「Index」字串,將會對應到Index.cshtml檔案。按F5來執行程式,在瀏覽器上輸入以下URL:

http://localhost:44913/Employee/Index

您可以看到Controller回傳的文字就會顯示在畫面上,請參考下圖所示:

clip_image031[4]

圖 19:View執行結果。

若修改EmployeeController Index action程式碼,回傳View時沒有指定名稱:

 

namespace MvcApplication1.Controllers {
  public class EmployeeController : Controller {
       public ActionResult Index( ) {
      ViewBag.Message = "執行EmployeeController Index action";
      return View();
    }
  }
}

您將發現,執行的結果和上個範例相同。這是因為當你沒有指定名稱時,會自動根據ASP.NET MVC命名習慣來找到Index.cshtml顯示。不過,您也可以指定Controller回傳不符命名習慣的其它檢視檔案,例如在Views\Employee目錄下新增一個Display.cshtml:


@{
  ViewBag.Title = "Display";
}
<h2> Display </h2>
<p> @ViewBag.Message </p>

 

再修改Controller,讓View方法傳入檢視名稱「Display」:

namespace MvcApplication1.Controllers {
  public class EmployeeController : Controller {
      public ActionResult Index ( ) {
      ViewBag.Message = "執行EmployeeController Index action" ;
      return View ( "Display" );
    }
  }
}

按F5來執行程式,在瀏覽器上輸入以下URL:

http://localhost:44913/Employee/Index

執行結果,請參考下圖所示:

clip_image033[4]

圖 20:顯示不同於Controller名稱的View。

 

使用模型(Model)

若我們希望網頁中可以顯示員工資料,你可以建立模型(Model)來存取資料。例如在目前的專案之中加入一個資料模型類別,從Visual Studio 2012開發工具-「方案總管」-你的專案-「Models」目錄上方按滑鼠右鍵,從快捷選單選擇「加入」-「類別」,設定名稱為「Employee」,然後按下「新增」按鈕,請參考下圖所示:

clip_image035[4]

圖 21:新增類別。

我們定義Employee類別中包含三個屬性:ID、Name與Age:

namespace MvcApplication1.Models {
  public class Employee {
    public int ID { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
  }
}

修改EmplyeeController,提供一個List Action,在方法中建立一個List泛型集合儲存5個Employee物件,並將此List泛型集合透過ViewBag傳到View:

 

namespace MvcApplication1.Controllers {
  public class EmployeeController : Controller {
     public ActionResult Index ( ) {
      ViewBag.Message = "執行EmployeeController Index action" ;
      return View ( "Display" );
    }

    public ActionResult List( ) {
      List<Employee> empList = new List<Employee> () {
        new Employee() { ID=1 , Name="Mary", Age=30 } ,
        new Employee() { ID=2 , Name="Candy", Age=32 } ,
        new Employee() { ID=3 , Name="Lilly", Age=62 } ,
        new Employee() { ID=4 , Name="Sally", Age=35 } ,
        new Employee() { ID=5 , Name="Mickey", Age=41 }
      };
      ViewBag.Employees = empList;
      return View ( );
    }
  }
}

 


接下來建立檢視,將滑鼠停留在List action程式碼上方,按滑鼠右鍵,從快捷選單選取「加入檢視」,在「加入檢視」對話盒,您可以設定檢視名稱,設定檢視引擎等等項目,再按下「加入」按鈕,請參考下圖所示:

clip_image036[4]

圖 22:建立檢視。

修改一下程式碼,利用Razor程式區塊(Code Block) 語法,透過 foreach迴圈讀取所有Employee的資料呈現在無序清單中:

@{
  ViewBag.Title = "List";
}
<h2> List </h2>
<ul>
  @foreach ( MvcApplication1.Models.Employee emp in ViewBag.Employees ) {
      <li> @emp.ID  @emp.Name  @emp.Age </li>
  }
</ul>

按F5來執行程式,在瀏覽器上輸入以下URL:

http://localhost:44913/Employee/List

執行結果,請參考下圖所示:

clip_image037[4]

圖 23:顯示員工清單。

您也可以不使用ViewBag來傳遞資料,修改程式碼,直接在Controller程式最後在View方法傳入List<Employee>:

 

public ActionResult List ( ) {
      List<Employee> empList = new List<Employee>() {
        new Employee() { ID=1 , Name="Mary", Age=30 },
        new Employee() { ID=2 , Name="Candy", Age=32 },
        new Employee() { ID=3 , Name="Lilly", Age=62 },
        new Employee() { ID=4 , Name="Sally", Age=35 },
        new Employee() { ID=5 , Name="Mickey", Age=41 }
      };
      return View ( empList );
    }

 

接著修改List.cshtml檔案,在上方加上@model宣告,表示將接收到Controller傳遞的IEnumerable<MvcApplication1.Models.Employee>型別,後續可以直接使用「Model」取出Controller傳入的List<Employee>:

@model IEnumerable<MvcApplication1.Models.Employee>
@{
  ViewBag.Title = "List";
}
<h2> List </h2>
<ul>
  @foreach ( MvcApplication1.Models.Employee emp in Model ) {
 
    <li> @emp.ID  @emp.Name  @emp.Age </li>
  }
</ul>

 

我們也可以改寫檢視,使用using語法,讓程式更精簡,例如修改List.cshtml程式為:

 

@using MvcApplication1.Models
@model IEnumerable<Employee>
@{
  ViewBag.Title = "List";
}
<h2> List </h2>
<ul>
  @foreach ( Employee emp   in ViewBag.Employees ) {
 
    <li> @emp.ID  @emp.Name  @emp.Age </li>
  }
</ul>

 

另一個做法,是在Web.Config檔案加上引用命名空間的程式碼:

<pages>
      <namespaces>
        <add namespace="MvcApplication1.Models" />
        <add namespace="System.Web.Helpers" />
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization" />
        <add namespace="System.Web.Routing" />
        <add namespace="System.Web.WebPages" />
      </namespaces>
    </pages>

然後List.cshtml程式,就不必寫using的宣告。

@model IEnumerable<Employee>
@{
  ViewBag.Title = "List";
}
<h2> List </h2>
<ul>
  @foreach ( Employee emp   in ViewBag.Employees ) {
 
    <li> @emp.ID  @emp.Name  @emp.Age </li>
  }
</ul>

 

使用ViewModel模型

有時一個檢視可能需要呈現多種資料,資料不是來自於單一資料模型物件,例如我們除了想要呈現員工清單之外,可能還想要顯示員工資料總計,以及員工負責的客戶名單…等等資料。有一個簡單的做法,就是定義一個ViewModel類別,將想要呈現在檢視中的東西全數封裝在此類別。讓我們來看看如何設計,在目前的專案加入一個類別,從Visual Studio 2012開發工具-「方案總管」-你的專案-「Models」目錄上方按滑鼠右鍵,從快捷選單選擇「加入」-「類別」,設定名稱為「EmployeesListViewModel」,然後按下「新增」按鈕,請參考下圖所示:

clip_image039[4]

圖 24:加入EmployeesListViewModel類別。

接著把想從Controller傳遞到檢視呈現的資料,包裝在EmployeesListViewModel類別,修改程式如下,定義兩個欄位:Employees存放員工清單;Count用來存放員工資料筆數。

namespace MvcApplication1.Models {
  public class EmployeesListViewModel {
    public IEnumerable<Employee> Employees;
    public int Count;
  }
}

修改Controller List action程式碼,建立EmployeesListViewModel物件,並初始化Employees與Count欄位,最後回傳Controller的View方法,並傳遞EmployeesListViewModel物件:

public ActionResult List( ) {
   List<Employee> empList = new List<Employee>() {
     new Employee() { ID=1 , Name="Mary", Age=30 } ,
     new Employee() { ID=2 , Name="Candy", Age=32 } ,
     new Employee() { ID=3 , Name="Lilly", Age=62 } ,
     new Employee() { ID=4 , Name="Sally", Age=35 } ,
     new Employee() { ID=5 , Name="Mickey", Age=41 }
   };

   EmployeesListViewModel vm = new EmployeesListViewModel() {
     Employees = empList ,
     Count = empList.Count
   };
   return View ( vm );
}

回頭過來修改List.cshtml檢視,將上方的model型別設定為EmployeesListViewModel,後續可以從Model.Employees取出員工清單;從Model.Count取出員工資料筆數。

@model MvcApplication1.Models.EmployeesListViewModel
@{
  ViewBag.Title = "List";
}
<h2> List </h2>
<ul>
  @foreach ( MvcApplication1.Models.Employee emp in Model.Employees ) {
 
    <li> @emp.ID  @emp.Name  @emp.Age </li>
  }
</ul>
  <br />
  員工總數: <b> @Model.Count </b>

 

按F5來執行程式,在瀏覽器上輸入以下URL:

http://localhost:44913/Employee/List

執行結果,請參考下圖所示:

clip_image040[4]

圖 25:使用ViewModel。

 

總結

本文介紹了ASP.NET MVC 4網站設計的第一步,讓您能夠利用MVC模式以及Visual Studio 2012的範本來了解ASP.NET MVC 4網站設計的基本概念。

Tags:

.NET Magazine國際中文電子雜誌 | 許薰尹Vivid Hsu | ASP.NET MVC

評論 (2) -

ASP.NET MVC能借鉴到java的框架里面吗

回覆

學生
學生 Taiwan
2015/12/8 上午 12:12:17 #

老師的文章真的很棒

回覆

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List