[Asp .Net MVC] Controller and View 的應用

[Asp .Net MVC] MVC 架構與說明 ( 以Asp .Net MVC C# 為例 )

本篇除了簡單說明 MVC 概念,也進一步說明 Asp .Net MVC Web Application 專案架構。
呈現環境為visual studio 2015 community:
連結:https://www.visualstudio.com/zh-tw/products/visual-studio-community-vs.aspx。

若有觀念錯誤或建議,也請各位先進不吝指導。

介紹

MVC 一種軟體架構模式,把系統分成三個種核心,分別為:Model, View, Controller。
主要將網頁分成邏輯處理(物件操作)、視覺呈現與路由控制(發送、接收請求),各種元件
處理不同的工作,強調職責分離,開發與維護人員可以更快速對於目的與問題,找到該
處理的程式,讓程式的修改與功能擴充簡化,提高程式可用性。

 

在不同的原件中,各有自己的特色:
Model : 包含所有的邏輯、物件,內容豐富。
Controller : 盡量輕量,這裡盡量不撰寫邏輯與物件,而以路由以傳遞資料為主。
View : 僅呈現,故盡量單純(笨笨)的呈現即可。

MVC架構的並不是容易做到,通常需要有良好的設計(或有相當經驗的架構師),才能將
工作分割的相當完美。早期MVC架構推廣相當不易,尤其對於小型專案,開發人員需要
花費大量時間在建構與維護MVC架構,其花費的成本遠大於小型專案的成本。雖然以大
型專案與專案長遠發展的角度來說,MVC架構是非常有幫助的,但入門門檻過於高,而
導致許多專案打退堂鼓。

但近年來,由於開發環境的成熟與各家語言、框架、套件等日新月異,MVC架構之維護
方式日趨簡易且一致,讓中、小型專案也不會因為維護複雜度高的缺點,無法導入MVC
架構,MVC架構也逐漸成為近年來開發主流方式之一。

簡單整裡MVC重點如下:

優點:
-使程式結構更加直覺
-增加程式可用性
-程式方便管理
-程式擴充性高
-有例於團隊開發

缺點:
-不適用於小型專案
-管理文件增加
-嚴謹的系統架構與規劃
-需要重覆的測試

下圖為一個示意圖,簡單介紹MVC在整個網頁系統流程:
使用者在網頁(View)表單(請求)送出後,皆會透過 Controller 接收後,決定給哪個model進行
處理。所有需求完成後,Controller 再回傳相對的結果,讓網頁(View)呈現相關資訊。

Asp .Net MVC Web Application 開啟範本專案操作步驟:
請依序下列步驟開啟一個範本專案:
Step 1.開啟 Visual Studio 2015,點選file -> new -> project
Step 2.選擇Web -> ASP.NET Web Application,點選OK
Step 3.點選MVC專案,點選OK,即可開啟範本專案。

Asp .Net MVC Web Application 架構說明:
一開始的範本專案,已經幫開發者做好分類,雖然開發者也可以依循自己的想法去更改
檔案位置,但個人還是強烈建議養成習慣,將各類型程式分類放置。Asp .Net MVC專案
的配置像相當好,開發者可以依循此架構開始專案(如下圖所示)。

個人的習慣除了下圖描述,個人會另開ViewModel放置ViewModel或DTO;另開Service放置
邏輯處理或呼叫API的程式;若撰寫angularjs,會另外建置一個app資料夾,放置相關js。
依據專案越來越大更改架構與配置。

重要的是,希望各個開發者以習慣代替配置,雖然MVC已經很明確將資料配置規定好,
但一個不注意,專案內的程式檔案就會亂放。團隊成員內相同的配置習慣一致,除了讓
專案好維護,在討論開發相關內容的更加順利。故每一位開發者,對於程式命名、配置
養成好的習慣,對專案開發是非常的有幫助的。
Routing Config
我們怎麼知道哪一個網址,對應哪一個 Controller 呢?
在專案中,我們透過 RouteConfig.cs 設定所有網址與Controller之間的對應。(上一篇的最後
,我們教您如何開啟一個範本Web application,我們以這個範本為例來進行說明)
我們可以在專案下找到 App_Start\RouteConfig.cs 這個檔案。

開啟 RouteConfig.cs,我們可以看到預設內容如下:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

routes.IgnoreRoute 的語法表示不要透過 Routing 處理的網址,下列表示
www.yourdomain.com/xxx.axd/xxx/xxx.. 格式網址不進行處理
(* 表示後面無論接幾個路徑,如:/xxx/xxx或/xxx/xxx/xxx,皆不處理)

routes.MapRoute 的語法表示 routing 的規則:www.yourdomain.com/controller/action/id
第一層為 controller 名稱、第二層為 action 名稱、第三層為 id ;而若沒有controller、action、
id,直皆輸入www.yourdomain.com,預設的對應的路由為 www.yourdomain.com/Home/Index

這裡有一個非常重要的規則,就是順序。 當你的撰寫順序錯誤錯誤,在後面的規則可能永
遠對應不到。當然,不是只有撰寫規則在RouteConfig.cs就好,我們必須於網頁應用程式起
點Global.asax.cs的Application_Start 註冊 RouteConfig.cs 才會啟用,如下圖所示:

Controller
完成了設定,我們要開始建立我們的 Controller 。
Controller程式的命名規則,後面皆需要加上 Controller,如: HomeController

點開 Controllers資料夾,可以看見預設的HomeController。 當中有許多方法,回傳值為
ActionResult,我們稱為Action:
當我們想要呼叫名稱為Index的Action,只需要在網址上輸入
www.yourdomain.com/Home/Index即可;
當我們想要呼叫名稱為About的Action,只需要在網址上輸入
www.yourdomain.com/Home/About即可...
依此類推。

 

每一個 Action 可以對應一個 View, 對應的位置為View資料下的.cshtml檔案:
Controllers\HomeController 裡面的 Index => Views\Home\Index.cshtml
Controllers\HomeController 裡面的 About => Views\Home\About.cshtml
簡單的說,進入不同的Action,就會得到不同的網頁內容。
當你寫好一個Action,你可以右鍵點選這個Action,選擇Add View,Visual Studio會自動
在對應的位置加上.cshtml檔案。

ActionResult
當然,不一定要回傳一個 View (如About.cshtml),你可以回傳一串文字、一張圖片、一
段 javascript 或是儲存很多資訊的json與xml字串,每種ActionResult使用方式不同,可以
參考:ActionResult 。JsonResult範例如下圖所示:

 

參考資料:

1.ASP.NET MVC 開發心得分享 (21):Routing 觀念與技巧
http://blog.miniasp.com/post/2011/08/01/ASPNET-MVC-Developer-Note-Part-21-Routing-Concepts-and-Skills.aspx

開啟範例程式,我們先開啟Views\Home\Index.html 進行改寫,內容如下:

我們增加一個Html form(使用Post方法)、兩個文字輸入框與一個送出按鈕,文字輸入框的
name 屬性,分別為name 與 age。
開啟Controllers\HomeController,我們修改程式內容如下:

我們另外增加了一個Index action,設定接收條件HttpPost (與form的方法相同), 並且給予兩個
傳入參數,名稱分別為 name 與 age(接入參數名稱必須與 input 內的 name 屬性名稱相同,才
能接到傳入參數)。

我們要怎麼確定資料有傳遞進入HomeController呢?
我們可以透過點擊編寫程式碼視窗邊框增加一個中斷點,啟動專案、輸入資料並且送出,
即可將程式執行停留在中斷點,此時只需要將滑鼠移到變數上,即可看見目前的內容值,
確認參數有正確傳遞。

在這個範例中,我們限制限制透過Http Post接收,若對應的方法不正確,會出現404 not found
的訊息。

在Asp .Net MVC中,資料傳遞的方式是透過input name對應進行傳遞,如果遭遇name相同的情
況下,傳入參數會變成list進行傳遞。當然,您如果曾經寫過Web form相關程式,也可以直接
擷取Ruquest的資訊進行處理:您可以參考這篇文章 [ASP .NET] Request.QueryString and Request.Form (ASP .Net MVC Example)

如何從從controller傳遞參數至View進行呈現

在後端,我捫常常需要將處理好的資訊,傳遞到View中進行呈現,常見的傳遞方式與作法
如下:




我們還沒帶入ViewModel的概念,故我們先不介紹ViewModel方法。
我們以ViewBag的方式,介紹如何簡單傳遞資料的方法,ViewBag有個好處,就是不需要處
理型別(dynamic 型別包裝),而取出使用的時候在進行轉換型別即可使用。

我們只需要在相對應的action中輸入ViewBag.變數,即可直接使用,例如:
ViewBag.Name = "Duran";

而在相對應的View上直接輸入@ViewBag.Name,在畫面上,即可直皆印出Duran的文字。

結果

如此一來,您已經可以處理一個簡單的表單送出的資訊,並且回饋簡單訊息給使用者。
當然,這非常的基礎。一般作法會使用ViewModel(DTO)的方式,將資料傳遞到View進行呈
現。透過ModelBinding的方式,可以作到資料驗證、呈現變更、資料過濾...等許多方便的功
能。在某些情境下,我們不需要更改.cshtml,只需更改ViewModel上的filter attribute,即可達
到不同的效果。

整個 View 的基本結構如下圖,可以分成:
1. Cotroller-Action 呈現內容
從前兩篇我們可以知道Controller與View的關係:Views 資料夾配置了許多對應Controller
的子資料夾,而每一個子資料夾的內部,有許多對應action的.cshtml(partial view)檔案。
2. 共用內容
除此之外,在範本專案中,您也可以發現多一個Shared資料夾,與_ViewStart.cshtml、
_Layout.cshtml等檔案。一般來說,Shared資料夾我們會放置一些通用 View,無論是不
是partial view,這些.cshtml檔案可以被其他的View所共用,後續介紹的display template與
editor template 也會放在這裡。

3. View 起點
在View底下,您能找到_ViewStart.cshtml 這支程式,這是所有 View 的起點。而運作流程如下:

點開後可以發現預設內容指向Shared 資料夾的_Layout.cshtml:

4. 整體版面
_Layout.cshtml 這支程式是呈現整個網頁的全貌 (html + css)。
一個現代的網站配置,大概可以分為 header, content, sidebar 與 footer等區塊(如下圖),
依據設計師的規劃,各個區塊有不同的用途與視覺效果。
(理所當然,依照網站呈現設計不同,呈現的樣式也不同,非一定呈現如此)。
而範本程式的配置如下:
_Layout.cshtml內容中,我們能找到 @RenderBody() 這個語法,功能是呈現內容(content):
目的是將 controller\action 所回傳的 view 嵌入在 _Layout 的@RenderBody() 所在位置。如此
一來,外部樣式(header, footer, or side bar)即可共用,網頁切換時,不需要每個畫面撰寫重
複的html,而只須依據不同的controller與action,嵌入不同的 view。

我們也能將其他header, sidebar區塊作為另外建立patial view,再使用 @Html.Partial 與
@Html.RenderPartial語法嵌入。當然,這又是另一種應用了。當_Layout.cshtml版面撰寫好
了,我們只需專注在每一個partial view即可。

在View,我們能夠使用完整Html、CSS與JavaScript進行編輯,但如果需要將處理過的
資料從Controller傳遞到View,或是想在View進行一些邏輯運算,仍需要憑藉的Razor語
法實現,而如果您還有印象,上一篇我們曾經使用@ViewBag來顯示訊息。
下一篇,我會簡單介紹 進階View使用:Razor與htmlHelper的語法。

文章出處  Asp.Net MVC 微軟社群之星2015

[Asp .Net MVC] MVC 架構與說明

Controller and View 1 - Controller 架構篇

Controller and View 2 - 資料傳遞篇

Controller and View 3 - View架構篇

3 Responses

  1. Eunice Synder
    Are you looking for effective online promotion that isn't completely full of it? I apologize for sending you this message on your contact form but actually that was kinda the point. We can send your ad text to websites via their contact pages just like you're receiving this note right now. You can target by keyword or just fire off mass blasts to sites in the location of your choice. So let's say you're looking to push through an ad to all the web developers in the United States, we'll grab websites for just those and post your ad text to them. As long as you're promoting a product or service that's relevant to that business category then you'll be blessed with awesome results! Send a quick note to muhammad2435tay@gmail.com for the full details
  2. Meredith Dendy
    Hello n95 masks directly from our factory in U.S.A. We have large stocks. Order here https://screenshot.photos/n95mask8 Regards "Sent from my Phone"
  3. Cory Genovese
    Hi, I was just checking out your website and filled out your feedback form. The contact page on your site sends you messages like this via email which is why you're reading through my message right now right? That's the most important achievement with any type of online ad, getting people to actually READ your message and I did that just now with you! If you have something you would like to blast out to millions of websites via their contact forms in the US or anywhere in the world send me a quick note now, I can even target specific niches and my pricing is very affordable. Write a reply here: trinitybeumer@gmail.com

Cory Genovese 發表迴響