創(chuàng)建ASP.NET Core MVC應用程序(1)-添加Controller和View

創(chuàng)建ASP.NET Core MVC應用程序(1)-添加Controller和View

參考文檔:Getting started with ASP.NET Core MVC and Visual Studio

這系列文章是參考了.NET Core文檔和源碼,可能有人要問,直接看官方的英文文檔不就可以了嗎,為什么還要寫這些文章呢择镇?

原因如下:

  • 官方文檔涉及的內容相當全面,屬于那種大而全的知識倉庫则拷,不太適合初學者段化,很容易讓人失去重要逛艰,讓人掉入到具體的細節(jié)之中赛惩。
  • 對于大多數人來講開發(fā)語言只是工具哀墓,程序員都有一個通病,就是死磕工具喷兼,把工具學深篮绰。我認為在工具上沒有必要投入太多時間,以能高效地完成日常的工作項目為準即可季惯。要需求驅動學習吠各,你需要什么學什么。如果你學的新技術新特性只是屠龍之技或者只需要用到的時候去查一下即可的話星瘾,這種死磕這又有什么用。沒有必要花120%的時間去學100%的知識惧辈,你只需要花20%的時間去學習80%的知識就可以了琳状,剩下的等實際的項目中用到的時候去查就可以了,工具只是工具,不是工作本身盒齿。
  • 目前基本所有的文章都是基于Windows平臺的Visual Studio IDE來介紹的念逞。而我用的是一臺Mac,所以我將基于Mac平臺的Visual Studio Code講解適合我們實際項目中遇到的知識边翁。
  • 還有一點翎承,就是這是我個人的學習總結。

這系列文章就是讓你去花20%的時間去學80%的東西符匾,剩下的20%再去看官方文檔叨咖。

之前介紹了《如何在Mac下運行ASP.NET Core應用程序》,主要是講解了如何在Mac下把ASP.NET Core跑起來,在這一篇中將進一步分析如何添加Controller甸各、View垛贤、Model等。

Model-View-Controller (MVC)?架構模式將一個應用程序分成了三大塊:Model趣倾、View聘惦、Controller

  • Models: 用于表示應用程序數據的類儒恋,并使用驗證邏輯來約束數據的業(yè)務規(guī)則善绎。通常模型對象用來從數據庫獲取和存儲實體模型?數據。比如User Model 從數據庫獲取用戶數據诫尽,并將它交給View來顯示或者直接更新禀酱,更新后的數據再寫入到數據庫中。
  • Views: 用來顯示應用程序UI的組件箱锐,該UI會顯示Model數據比勉。
  • Controllers: 是Models和Views的一個橋梁。用來處理瀏覽器請求驹止,獲取Model數據浩聋,并將指定視圖模板作為響應返回給瀏覽器。視圖(View)僅僅用于顯示信息臊恋,控制器(Controller)用于處理并響應用戶的輸入和交互衣洁。比如,Controller處理路由數據查詢字符串值抖仅,并將這些值傳遞給Model坊夫,Model再去使用這些值去查詢數據庫。

MVC模式幫助你創(chuàng)建一個關注分離的應用程序(輸入邏輯撤卢、業(yè)務邏輯环凿、UI邏輯),同時這個模塊之間是松耦合的。UI邏輯屬于View放吩,輸入邏輯屬于Controller,業(yè)務邏輯屬于Model智听。

添加Controller

namespace MyFirstApp.Controllers
{
    public class HomeController : Controller
    {
        // GET: /<controller>/
        public IActionResult Index()
        {
            return View();
        }

        // GET: /<controller>/About
        public IActionResult About()
        {
            ViewData["Message"] = "Your application description page.";

            return View();
        }

        public IActionResult Contact()
        {
            ViewData["Message"] = "Your contact page.";

            return View();
        }

        public IActionResult Error()
        {
            return View();
        }

        public IActionResult Welcome(string name, int id = 1)
        {
            ViewData["Message"] = "Hello " + name;
            ViewData["id"] = id;

            return View();
        }
    }
}

在控制器中的每一個public方法都可以作為HTTP終結點被調用。

第一個注釋表示這是一個通過在根URL添加“/Home/”進行調用的HTTP GET方法渡紫。第二個注釋表示這是一個通過在根URL添加"/Home/About/"來進行調用的HTTP GET方法到推。

MVC根據傳入的請求URL調用相應的控制器類以及其中的Action方法,MVC默認使用的URL路由邏輯采用類似于這樣的格式來決定具體的代碼調用:

/[Controller]/[ActionName]/[Parameters]

打開Startup.cs你會看到該項目的路由規(guī)則:

當你不帶任何URL段(segment)直接運行該程序時惕澎,將默認訪問“Home”控制器中的"Index"方法莉测。

第一個URL segment決定運行哪個Controller,所以http://localhost:5000/Home映射到HomeController類;URL segment第二個部分決定類里面的Action方法唧喉。所以http://localhost:5000/Home/Index會運行HomeController類中的Index方法捣卤;URL segment的第三部分(id)是路由數據忍抽。

這里通過增加一個方法來顯示通過URL傳遞一些參數信息到Controller。

public string Welcome(string name, int id = 1)
{
    return HtmlEncoder.Default.Encode($"Hello {name}, id: {id}");
}

上述代碼通過使用HtmlEncoder.Default.Encode來保護應用免受JS的惡意輸入腌零,并且使用了C#的新特性Interpolated Strings梯找。

http://localhost:5000/Home/Welcome?name=Charlire&id=1

MVC的模型綁定系統自動將查詢字符串的命名參數映射到具體的方法中的參數,注意名稱必須一致益涧。

上述代碼中URL segment(Parameters)沒有被使用到锈锤,參數nameid都是作為查詢字符串被傳遞的。?是一個分隔符闲询,后面跟著的就是查詢字符串久免,&用來分割查詢字符串。

輸入下面的URL:http://localhost:5000/Home/Welcome/1?name=Charlire扭弧。這一次第三個URL segment將匹配到路由參數id阎姥。Welcome方法包含一個與MapRoute方法中的URL模板相匹配的id參數。隨后的?(id?)表示id參數是可選的鸽捻。

添加View

通過Razor視圖引擎創(chuàng)建視圖模板文件呼巴,基于Razor的視圖模板使用 .cshtml 作為文件擴展名,通過使用C#提供了一個優(yōu)雅的方式來創(chuàng)建HTML御蒲。

public IActionResult Index()
{
    return View();
}

上面的Index方法使用視圖模板來生成一個HTML響應給瀏覽器衣赶。Controller中的Action方法通常返回一個IActionResult(或一個派生于ActionResult 類),而不是像String這樣的基元類型厚满。

點擊Views文件夾府瞄,在該文件夾下面新建與Controller名對應的文件夾。

然后我們導航到Views->User文件夾碘箍,運行命令yo aspnet:mvcview Index在該文件夾下面生成Index.cshtml遵馆。

Index方法只是簡單地運行了return View(),來指定方法去使用一個視圖模板文件來為瀏覽器渲染最新的響應丰榴。因為沒有顯式指定所要使用的視圖模板文件货邓,MVC會默認使用 /Views/User 文件夾中的 Index.cshtml

改變視圖和布局頁面

通用點擊菜單鏈接四濒,你會發(fā)現每一個頁面都顯示了相同的菜單布局换况,這個菜單布局位于 Views/Shared/_Layout.cshtml 文件。

Layout模板允許你在一個地方指定網站的HTML容器布局峻黍,并應用到網站的多個頁面中复隆。@RenderBody()是一個占位符拨匆,用來顯示你指定視圖的位置姆涩,“包裹在”布局頁面。舉個例子惭每,當你點擊About鏈接骨饿,Views/Home/About.cshtml視圖就會在RenderBody?方法內渲染亏栈。

修改Layout文件中的標題和菜單鏈接

注意現在每一個頁面都顯示了新修改的鏈接,通過在Layout模板中修改一次宏赘,網站上的所有的頁面都立即顯示成新修改的信息绒北。

通過查看 Views/_ViewStart.cshtml 文件:

@{
    Layout = "_Layout";
}

Views/_ViewStart.cshtml 文件將 Views/Shared/_Layout.cshtml 文件引入到每一個視圖中。你可以通過Layout屬性來設置一個不同的布局視圖察署,或將它設置成null闷游,那么將不使用任何一個布局文件。

修改 Views/User/Index.cshtml 文件如下:

@{
    ViewData["Title"] = "User List";
}

<h2>User List</h2>

<p>Hello from View Template!</p>

ViewData["Title"] = "User List";ViewDataDictionaryTitle屬性設置為User List贴汪。這個Title屬性將用在 Views/Shared/_Layout.cshtml Layout頁面的<title>?HTML元素上脐往。

<title>@ViewData["Title"] - User MVC Application</title>

注意 Index.cshtml 視圖模板中的內容是怎么和 Views/Shared/_Layout.cshtml 視圖模板進行合并的,布局模板使得修改應用里所有的頁面很容易扳埂。

從Controller傳遞數據到View

在談到數據庫和模型(Models)之前业簿,先讓我們討論一下從控制器傳遞信息到視圖⊙舳控制器方法會在傳入的URL請求響應時被調用梅尤。控制器類是用于處理傳入的瀏覽器請求岩调,從數據庫獲取數據巷燥,并最終決定哪種類型的的響應會被回傳給瀏覽器。

控制器主要負責提供視圖模板向瀏覽器呈現一個響應所需的數據或對象誊辉。

最佳實踐:視圖模板不應該執(zhí)行業(yè)務邏輯或直接與數據庫進行交互矾湃,而只應該使用控制器提供給它的數據。保持這樣的“關注分離”有助于保持你的代碼整潔堕澄,可測試性及更易于維護邀跃。

當前,HomeController控制器中的Welcome方法接受一個name蛙紫、id參數拍屑,然后直接將值輸出到瀏覽器。我們在控制器中將使用一個視圖模板來代替字符串坑傅,視圖模板將生成一個動態(tài)響應僵驰,這就意味著你需要通過控制器傳遞適當的數據給視圖來生成響應,可以讓控制器將視圖模板需要的動態(tài)數據(參數)放入ViewData字典中唁毒,隨后視圖模板可以通過訪問該字典獲取到這些數據蒜茴。

ViewData字典是一個動態(tài)對象,你可以將任何你想要的數據加進去浆西。在你加入數據之前粉私,ViewData對象沒有任何已定義的屬性。MVC的模型綁定系統自動映射地址欄中查詢字符串的命名參數到你方法中的參數近零。

public IActionResult Welcome(string name, int id = 1)
{
    ViewData["Message"] = "Hello " + name;
    ViewData["id"] = id;

    return View();
}

ViewData字典對象包括將要傳遞到視圖的數據诺核。接受抄肖,我們來創(chuàng)建一個Welcome視圖模板。

這里將在Welcome.cshtml視圖模板中創(chuàng)建一個循環(huán)窖杀。

@*
    For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
    ViewData["Title"]= "Welcome Page";
}
<h2>Welcome</h2>

<ul>
    @for(int i=0; i<(int)ViewData["id"]; i++)
    {
        <li>@ViewData["Message"]</li>
    }
</ul>

數據從URL獲得并通過MVC模型綁定器傳遞到控制器漓摩,控制器將數據打包封裝到ViewData字典中并將該對象傳遞給視圖。接著入客,視圖將數據以HTML的形式渲染到瀏覽器管毙。

我們使用了一個ViewData字典來將數據從控制器傳遞到視圖,接下來我們將使用視圖模型(View Model)來實現相同的目的桌硫。通過View Model來傳遞數據比通過ViewData更受歡迎锅风。

個人博客

我的個人博客

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鞍泉,隨后出現的幾起案子皱埠,更是在濱河造成了極大的恐慌,老刑警劉巖咖驮,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件边器,死亡現場離奇詭異,居然都是意外死亡托修,警方通過查閱死者的電腦和手機忘巧,發(fā)現死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睦刃,“玉大人砚嘴,你說我怎么就攤上這事∩荆” “怎么了际长?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長兴泥。 經常有香客問我工育,道長,這世上最難降的妖魔是什么搓彻? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任如绸,我火速辦了婚禮,結果婚禮上旭贬,老公的妹妹穿的比我還像新娘怔接。我一直安慰自己,他們只是感情好稀轨,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布扼脐。 她就那樣靜靜地躺著,像睡著了一般靶端。 火紅的嫁衣襯著肌膚如雪谎势。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天杨名,我揣著相機與錄音脏榆,去河邊找鬼。 笑死台谍,一個胖子當著我的面吹牛须喂,可吹牛的內容都是我干的。 我是一名探鬼主播趁蕊,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼坞生,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掷伙?” 一聲冷哼從身側響起是己,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎任柜,沒想到半個月后卒废,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡宙地,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年摔认,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宅粥。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡参袱,死狀恐怖,靈堂內的尸體忽然破棺而出秽梅,到底是詐尸還是另有隱情抹蚀,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布企垦,位于F島的核電站况鸣,受9級特大地震影響,放射性物質發(fā)生泄漏竹观。R本人自食惡果不足惜镐捧,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望臭增。 院中可真熱鬧懂酱,春花似錦、人聲如沸誊抛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拗窃。三九已至瞎领,卻和暖如春泌辫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背九默。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工震放, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人驼修。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓殿遂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親乙各。 傳聞我的和親對象是個殘疾皇子墨礁,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內容