MVC系列1-MVC基础
? 終于決定寫一個系列的文章了,最開始其實是準(zhǔn)備寫一下WPF的,因為我這兩年一直在做WPF,對WPF的喜愛自然是無以言表。但是由于我所在的地區(qū)對WPF的普及不是很廣泛,所以,被迫又開始做起來web,但是我又不想在傳統(tǒng)的web froms上工作。固而開始研究MVC。在看完了一本入門級的MVC書籍之后,我又轉(zhuǎn)而開始愛上MVC。它輕量,簡潔,擴展性和對html的深度控制這些特性會打破ASP.NET的開發(fā)模式。但是,也不是說MVC就能解決一切問題。它就是所有的編程模式中最好的,它也會有它的一些不足。可是我們想想,世界上有什么東西又會是完美的呢?對于我們程序員而言,語言,IDE就是我們工具。只要用著順手,能寫出高效的代碼就行了。管它誰人說那種語言好還是不好呢。廢話說得有點多,我更新這個系列的文章是為了對自己學(xué)習(xí)的一個總結(jié),并且分享給尚在學(xué)習(xí)階段的兄弟。在園子里寫得比我好的大牛很多。所以,歡迎指正錯誤與不足。
? 既然這是介紹MVC,那我們就來說說什么是MVC。傳統(tǒng)的MVC其實是一種理念。旨在分離關(guān)注點。及把我們的系統(tǒng)按照不同的關(guān)注點分離開來。這樣系統(tǒng)以各自的關(guān)注點分離開來。整個系統(tǒng)的可維護性,擴展性都會大大的提高。整個系統(tǒng)的層次結(jié)構(gòu)也會更加的清晰。我們這里所談的MVC其實是ASP.NET MVC。ASP.NET MVC其實是一種框架。以ASP.NET為平臺的框架,也就是說,其實它其實還是運行在ASP.NET運行時上的,微軟根據(jù)MVC的理念,在ASP.NET上封裝了一套遵循了MVC理念的框架。我們的程序在理論上大部分的時候是在處理數(shù)據(jù),而數(shù)據(jù)的處理方式是遵循特定行業(yè)的特定業(yè)務(wù)邏輯。以界面來展示數(shù)據(jù)。那么至少從這里我們可以抽象出一下幾個關(guān)注點
- ? 界面
- ? 界面邏輯
- ? 業(yè)務(wù)邏輯
- ? 數(shù)據(jù)
? 在這個時刻,我們至少是可以總結(jié)出以上的關(guān)注點,遵循分離關(guān)注點的原則,我們至少要把這些關(guān)注點給分離開來。
? 在這里,我們是把數(shù)據(jù)和業(yè)務(wù)邏輯放在了一起。因為從領(lǐng)域編程的角度,數(shù)據(jù)也好,業(yè)務(wù)邏輯也好。他們都是屬于某些特定領(lǐng)域的。比如金融領(lǐng)域,航空領(lǐng)域。所以這里他們是可以放在一起的,其中還會包括一些其他的,比如驗證,屬性標(biāo)注等等。
? 我們看上面的一張圖可以看到。關(guān)注點被分離。MVC的全稱是Model-View-Controler。這里不正是我們關(guān)注的分離點嗎
?
? 從這里我們可以總結(jié)以下的概念
? 視圖:一個動態(tài)生成HTML頁面的模板
? 模型:模型是描述程序設(shè)計人員感興趣問題域的一些類,這些類通常封裝存儲在數(shù)據(jù)庫中的數(shù)據(jù),以及操作這些數(shù)據(jù)和執(zhí)行特定域業(yè)務(wù)邏輯的代碼。在ASP.NET MVC中,模型就像是一個使用了某個工具的數(shù)據(jù)訪問層,包括實體框架。
? 控制器:一個協(xié)調(diào)視圖和模型之間關(guān)系的特殊類。它響應(yīng)用戶輸入,與模型進行對話,并決定呈現(xiàn)哪個視圖。
?? 我們現(xiàn)在來具體的解讀他們之間的聯(lián)系和各組件之間是怎么通訊和協(xié)作的,首先,我們來看View,View的作用很直接,就是現(xiàn)實用戶的數(shù)據(jù),獲取用戶的交互。也就是獲取輸入然后經(jīng)過處理展現(xiàn)數(shù)據(jù)。上面一句話提到了“經(jīng)過處理”,這里就又有了另外的一個問題,經(jīng)過什么處理,什么東西來處理。其實就是我們的Controler。它獲取用戶的輸入,經(jīng)過自己的處理邏輯然后將數(shù)據(jù)處理操作交給Model進行處理。Model處理了業(yè)務(wù)邏輯,完成數(shù)據(jù)之后會有兩種操作,一是由Controler處理界面邏輯,更新數(shù)據(jù),然后View展現(xiàn)數(shù)據(jù)。第二種方式是處理完數(shù)據(jù),由數(shù)據(jù)直接反應(yīng)更改到View。這個時候是不經(jīng)過Controler處理界面邏輯的,他們之間的關(guān)系是一個三角關(guān)系。可以從下面的一張圖來看出他們之間的關(guān)系。
? 從上圖我們可以看到M-V-C之間的通訊。這些都只是理論層面上的,從代碼層面我們現(xiàn)在還沒有看到代碼的執(zhí)行過程。下面我們來看一個最簡單的MVC程序,執(zhí)行的深層原理我們以后再講,這一章我們只是看一個最簡單的程序,看看MVC的執(zhí)行過程。
? 首先,我們需要創(chuàng)建項目,打開VS,新建一個MVC空項目。這里順便多說一句為什么是空項目。因為這樣VS不會幫我們創(chuàng)建范例代碼。如果不選擇空程序,VS會幫我們創(chuàng)建一些范例代碼來讓我們了解MVC。
我們這里選擇空模板,視圖引擎我們選擇Razor。視圖引擎指的是我們操作界面的方式。比如怎么利用數(shù)據(jù)組合html。這里我們不用深究Razor,以后的章節(jié)會講到Razor。測試項目我們這里暫時就不創(chuàng)建,因為我們單單就是一個示例程序,不需要那么復(fù)雜。創(chuàng)建項目之后我們可以看到如下的文件夾結(jié)構(gòu)。
這里我們解釋一下各個文件夾的用途
- App_Data:存放應(yīng)用程序的數(shù)據(jù)文件,比如數(shù)據(jù)庫文件,XML等等。
- App_Start:存放應(yīng)用程序啟動時需要的些類,這里是路由和路由注冊的類(路由的概念以后會講到)
- Controlers:Controler類的存放目錄
- Models:Model的存放目錄
- Views:View的存放目錄
- Global.asax:全局處理,包含應(yīng)用程序啟動時需要執(zhí)行的代碼,這里是使用App_Start里面的一類來注冊路由
- packages.config:NuGet包管理(暫時不需要了解,以后會講到)
- web.config :這個大家都很熟悉了,網(wǎng)站的配置文件
? 按照一般的文件夾結(jié)構(gòu)應(yīng)該是還會有Content這個文件夾,至少在VS2010里是有這個文件件夾的,但是我這里的VS2012是沒有這個文件夾的。這個文件夾存放的是網(wǎng)站的一般資源文件,比如js腳本,圖片,CSS文件等等,如果沒有我們可以手動添加一個,或者添加一些我們自己的文件夾。好了,項目我們是新建出來了,那么,我們該怎么開始呢?我們前面講到了MVC實際就是Model-Controler-View。我們就從這里開始。首先我們新建一個Contrler,命名為HoneControler。具體的步驟是我們可以右鍵點擊Controllers文件夾,添加Controller。
? 我們可以看到如下的界面,這里我們一切留空,除了命名。模板我們以后再來深入的了解。這里我們只是簡單的看看MVC怎么執(zhí)行的。點擊確定之后我們可以看到如下的代碼
namespace FirstMVC.Controllers {public class HomeController : Controller{//// GET: /Home/public ActionResult Index(){return View();}} }View Code
? 下一步我們修改生成的代碼,我們把返回類型改為string,然后返回一個字符串
namespace FirstMVC.Controllers {public class HomeController : Controller{//// GET: /Home/public string Index(){return "Welcome, MVC";}} }View Code
? 下面我們就可以直接啟動項目了,我們可以看到路徑是http://localhost:3222/之類的。我們在Index中返回的字符串直接輸出到瀏覽器。這里我們就完成了一個最簡單的MVC。但是這個例子是不夠來解釋我們MVC的整體執(zhí)行過程的。我們在這個例子的基礎(chǔ)上擴展來說明執(zhí)行過程。這里,我們一步一步的來完成我們完成的數(shù)據(jù)讀取的示例。
? 我們添加一個方法到我們的HomeController,方法名為ShowMessage。
public ActionResult ShowMessage(){return View();}View Code
? 這里需要先解釋這幾句代碼,這里定義了一個返回值為ActionView的方法。ActionView是 一個抽象類型,是指操作(這里是ShowMessage方法)的結(jié)果,我們這里的結(jié)果就是返回一個View,也就是我們的視圖。可以看到我們直接返回了View()。這里我們需要再解釋一個概念-約定優(yōu)先于配置
約定優(yōu)先于配置:在以前的很多時候,我們在想要自定義應(yīng)用程序中的一些行為時我們會使用配置文件,或者使用配置文件來制定應(yīng)用程序中的一些特定行為。約定優(yōu)先于配置是后來提出的一種概念。它的理念是大家一致遵守一種約定以取代配置對程序的特定行為的指定。這里我們的約定就是
- 控制器類以Controller結(jié)尾
- 在View文件夾下有一個與控制器同名的文件夾存在
- View文件夾下與Controller同名的文件夾下的視圖(.cshtml-一種新的類型)的名稱與控制器中Action(方法)名稱相同。
? 所以,這里當(dāng)我們直接Retrue View()的時候,解釋引擎會直接找到View----Home----ShowMessage視圖。所以下面,我們需要添加一個與ShowMessage方法對應(yīng)的View。我們可以右鍵點擊ShowMessage方法。選擇添加視圖。就會生成對應(yīng)的視圖。
@{Layout = null; }<!DOCTYPE html><html> <head><meta name="viewport" content="width=device-width" /><title>ShowMessage</title> </head> <body><div><h1>This is ShowMesage Page!</h1></div> </body> </html>View Code
? 到這里我們的控制器和視圖已經(jīng)定義完成。打開瀏覽器輸入http://localhost:3222/Home/ShowMessage我們可以看到我們在ShowMessage.CSHTML中的h1標(biāo)簽的內(nèi)容。這里需要注意一點,URL的端口請于自己機器具體端口相關(guān)。好了,到了這里,我們要解釋程序的執(zhí)行過程了。
? 當(dāng)URL進入通道后,運行時會感覺URL配置來獲取Controller,Action和參數(shù),URL路由的配置在RouteCongfig類中,代碼如下
public class RouteConfig{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });}}View Code
? 我們可以看到這里定義了路由規(guī)則url: "{controller}/{action}/{id}"不同的部件以“/”隔開。所以這里劃分我們的URL,Home就是控制器的名稱,ShowMessage就是Action的名稱,參數(shù)我們這里沒有。所以根據(jù)劃分得到的URL,下面的執(zhí)行步驟就是實例化HomeController調(diào)用ShowMessage方法,而ShowMessage方法返回的是ShowMessageView。所以,我們就可以在瀏覽器中看到ShowMessageView了。
在URL路由規(guī)則中,有一行代碼defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },這里指定的是默認(rèn)值,也就是當(dāng)我們的URL沒有指定Controller,Action,參數(shù)時的默認(rèn)值。回到上面我們最開始的URLhttp://localhost:3222/。這里,我們沒有指定Controller,Action。所以運行時會使用默認(rèn)的路由配置來填充URL。這里就會指向http://localhost:3222/Home/Index。
? 我們使用了一個示例解釋了MVC的執(zhí)行過程,但是這里可以看到,我們的示例完全只使用了C和V,沒有使用Model。所以,我們繼續(xù)完善我們的示例,加入數(shù)據(jù)操作,在Model文件夾下新建一個實體類Person。
public class Person{private int _personId;public int PersonId{get { return _personId; }set { _personId = value; }}private string _firstName;public string FirstName{get { return _firstName; }set { _firstName = value; }}private string _lastName;public string LastName{get { return _lastName; }set { _lastName = value; }}public Person(){this.PersonId = 1;this.FirstName = "Edrick";this.LastName = "Liu";}}View Code
? 在HomeController中添加一個新的Action,名稱為ShowPerson,添加完Action之后添加對應(yīng)的View,我們要使用這個View來顯示Person的數(shù)據(jù)。
public class HomeController : Controller{//// GET: /Home/public string Index(){return "Welcome, MVC";}public ActionResult ShowMessage(){ return View();}public ActionResult ShowPerson(){Person person = new Person();ViewBag.Person = person;return View();}}View Code
? ShowPerson View代碼如下
@{Layout = null; }<!DOCTYPE html><html> <head><meta name="viewport" content="width=device-width" /><title>ShowPerson</title> </head> <body><div><p>@ViewBag.Person.PersonId</p><p>@ViewBag.Person.FirstName</p><p>@ViewBag.Person.LastName</p></div> </body> </html>View Code
? 在HomeController中,我們實例化了Person并且在實例化的時候插入了數(shù)據(jù)。并且把person裝入ViewBag中以供視圖使用。這里也就是使用Controller建立了View和Model的聯(lián)系,但是這種聯(lián)系是弱類型的。并不是直接建立在View和Model之間的。這里我們先只了解ViewBag實際是一個數(shù)據(jù)集合。以后會詳細(xì)的解釋ViewBag。
? 最后,在瀏覽器中鍵入地址http://localhost:3222/Home/ShowPerson 可以看到我們的person數(shù)據(jù)。這樣我們就完成了一個典型的MVC程序。當(dāng)然也是最簡單的,我們先只需要了解什么是MVC,MVC是怎么執(zhí)行的等等。以后的章節(jié)我們會詳細(xì)解析每一個模塊。
?
?
?
?
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/ColeLiu/p/MVC.html
總結(jié)
以上是生活随笔為你收集整理的MVC系列1-MVC基础的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: myeclipse 遇到的一些问题及解决
- 下一篇: 一个比较保守的404页面