iT邦幫忙

2022 iThome 鐵人賽

DAY 3
1
Software Development

C# ASP.NET MVC實作: 30天打造屬於你的網站應用程式系列 第 3

(DAY 3)C# ASP .NET MVC實作: 30天打造屬於你的網站應用程式-新增Controller

  • 分享至 

  • xImage
  •  

接續前一天的專案,今天我們開始介紹Controller(控制器)的用法,不過在說明之前,我想要提一下和Controller相關的兩個東西:路由(Route)、和HTTP請求方法

● 路由(Route)

ASP .NET MVC 是藉由路由(Route)規範方式將URL模式連結到Controller,網址路由是定義在「App_Start」資料夾中的「RouteConfig.cs」檔案裡,我們打開這個檔案來一探究竟。

觀察圖片中框起來的程式碼,這裡即是定義路由的一組預設規範。預設路由表包含名為「Default」的單一路由,預設路由會將 URL 的第一個區段{controller}對應至控制器名稱、URL 的第二個區段{action}對應至控制器動作,並將第三個區段{id}對應至名為 id的參數。

我們實際來看Controllers資料夾底下的「HomeController.cs」檔案,控制器名稱就是類別名稱「HomeController」前面的「Home」;以底下的 public ActionResult Index() 這個方法來說,控制器動作就是方法名稱「Index」;因為方法本身沒有帶參數,所以可以忽略id。在還沒將網站部署前,網址的最前面會是像「https://localhost:44349」 這樣 Domain + Port號的形式,後面的數字會不太一樣,所以整合一起,這個控制器方法對應出來的網址就會是「https://localhost:44349/Home/Index 」
同理,另外兩個方法對應到的網址就是「~/Home/About」 與 「~/Home/Contact」。

        //GET: Home/Index
        public ActionResult Index()
        {
            return View();
        }

        //GET: Home/About
        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        //GET: Home/Contact
        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }

最後補充說明,預設路由表底下有一行

defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

這邊指的是,當如果URL後面沒有帶任何路由區段,僅有Domain + Port (像這樣 https://localhost:44349 ),它一樣會導到 ~/Home/Index 網址。所以我們可以嘗試將action改成 "About" 看看,執行後就會發現預設頁面變成About的畫面囉~路由的說明就暫時先到這邊

defaults: new { controller = "Home", action = "About", id = UrlParameter.Optional }

● HTTP請求方法

HTTP是一套網路傳輸協定,一般來說傳輸資料的兩端會分為 客戶端(Client) 和 伺服器端(Server),客戶端發送「請求(Request)」給伺服器端,伺服器端接收請求並「回應(Response)」客戶端,而我們現在看到網頁的資訊其實就是靠許多的 Request 與 Response 所形成。

在HTTP/1.1協定中共定義了八種方法(也叫「動作」)來以不同方式操作指定的資源:
OPTIONS
GET
HEAD
POST
PUT
DELETE
TRACE
CONNECT

詳細可以參考維基百科的說明:
https://zh.wikipedia.org/zh-tw/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE#%E8%AF%B7%E6%B1%82%E6%96%B9%E6%B3%95
實際上最常用的是GET 與 POST方法,所以我們關注在這兩項:

GET
向指定的資源發出「顯示」請求。使用GET方法應該只用在讀取資料,而不應當被用於產生「副作用」的操作中,例如在網路應用程式中。其中一個原因是GET可能會被網路爬蟲等隨意存取。參見安全方法。瀏覽器直接發出的GET只能由一個url觸發。GET上要在url之外帶一些參數就只能依靠url上附帶querystring。

POST
向指定資源提交資料,請求伺服器進行處理(例如提交表單或者上傳檔案)。資料被包含在請求本文中。這個請求可能會建立新的資源或修改現有資源,或二者皆有。每次提交,表單的資料被瀏覽器用編碼到HTTP請求的body里。瀏覽器發出的POST請求的body主要有兩種格式,一種是application/x-www-form-urlencoded用來傳輸簡單的資料,大概就是"key1=value1&key2=value2"這樣的格式。另外一種是傳檔案,會採用multipart/form-data格式。採用後者是因為application/x-www-form-urlencoded的編碼方式對於檔案這種二進位的資料非常低效。

如果是第一次看到上面這段說明,相信看完應該還是會覺得霧煞煞,我們先大概簡單記得:

GET: 用於發出「顯示」請求,且使用GET方法應該只用在讀取資料。
POST: 用於提交資料,請求伺服器進行處理(例如提交表單或者上傳檔案)。

詳細的比較差異,我們等講到form表單提交的時候再來說明吧~

● 新增控制器

那麼大概講完路由與HTTP請求方法的概念後,終於可以來進入今天的正題-新增Controller啦!
新增的步驟如下:

  1. 在Controller資料夾上按滑鼠右鍵 → 「加入」→ 點擊「控制器」

  2. 選擇 「MVC5 控制器-空白」項目,並點擊「加入」

  3. 這邊我們修改控制器名稱,就隨意改叫做「DemoController」好了,改完後點擊「加入」

  4. 控制器新增完成! 且發現控制器類別底下預設會生成一個 Index()方法

● 控制器撰寫與動作方法規範

接著說明Controller的一些規範如下:

  1. Controller類別須為public 公開,且會繼承「Controller」類別
  2. 類別名稱須為「Controller」結尾,ex: HomeControllerDemoController
  3. 類別底下的方法必須為public才能被呼叫執行,對應至指定的URL,這稱為動作方法(Action Method),如果方法非public則會被視為一般的方法。舉例來說,如果將範例的「HomeController」底下的Index()方法改成private,呼叫對應的URL(~Home/Index) 時就會發生錯誤
        //GET: Home/Index
        private ActionResult Index()
        {
            return View();
        }

  1. 動作方法回傳的值可以是字串、檔案、ActionResult、ViewResult...等等
  2. 動作方法可以指定HTTP請求方法的屬性,預設為GET傳送方式

● 新增動作方法

我們試著在DemoController Index()方法下面,再建立一個新的方法如下:

    public class DemoController : Controller
    {
        // GET: Demo
        public ActionResult Index()
        {
            return View();
        }
        
        //GET: Demo/ShowHelloWorld
        [HttpGet] //可省略
        public string ShowHelloWorld()
        {
            return "Hello World!";
        }
    }

可以發現在ShowHelloWorld()方法上面多了一行[HttpGet],代表是用GET方式發出請求,因為動作方法預設就是用GET傳送,所以實際上可省略不寫。
執行偵錯後輸入網址: https://localhost:44349/Demo/ShowHelloWorld
執行結果如下:

接著我們再新增一個動作方法如下:

        [HttpGet] //可省略
        public string ShowPrice(string product, int price)
        {
            return $"商品是:{product},價格是:{price}";
        }

當使用HTTP GET傳送資料時,是將資料放在URL後面再發出請求的,這次我們新增的方法多了2個參數,代表要在URL後方增加這些參數發出請求。輸入方式是在URL後面加上「?參數名稱=參數值」,如果有多個參數則用 & 符號連接在一起。
執行偵錯後輸入網址: https://localhost:44349/Demo/ShowPrice?product=熱狗&price=50
執行結果如下:

最後我們回來看看DemoController原本預設就建立好的Index()方法吧!

        // GET: Demo
        public ActionResult Index()
        {
            return View();
        }

你會發現這個方法回傳的是一個ActionResult的型別,ActionResult類別其實是所有動作方法結果的基底類別。例如我們將滑鼠移動到程式碼的View()上,會發現它其實是回傳一個叫ViewResult型別的結果,這個結果會將檢視顯示成網頁。

點進去ViewResult類別裡面看發現繼承的是ViewResultBase類別

再點進去ViewResultBase類別裡看,發現繼承最基底的類別就是ActionResult

另外還有許多的動作方法結果同樣是繼承ActionResult的,例如:RedirectToAction()HttpNotFound()Content()....等等,這邊先不一一說明,最後面有機會的話再補充。

● 小結

今天講了許多關於控制器相關的內容以及底下的動作方法,我們可以了解到,要顯示什麼網頁的檢視內容,其實是來自這些方法對應到的網址路由。明天我們將會進行如何新增View檢視的部分,那麼就明天見啦~

※小弟不才,在軟體的世界還只是個小菜雞,如果內容有任何謬誤或問題,還請各位大神前輩們多多批評指教~歡迎下方留言討論^^


上一篇
(DAY 2)C# ASP .NET MVC實作: 30天打造屬於你的網站應用程式-建立第一個網站應用程式
下一篇
(DAY 4)C# ASP .NET MVC實作: 30天打造屬於你的網站應用程式-新增View 與 資料傳遞(一): ViewData、ViewBag、TempData
系列文
C# ASP.NET MVC實作: 30天打造屬於你的網站應用程式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言