上一章筆者講到關於Asp.NET的知識點。了解Asp.NET基本的知識點之後,我們在來學習關於C#的MVC框架就簡單多了。顯然本章就是來介紹一下關於Asp.NET MVC。對於MVC的思想筆者相信大家已經很清楚了。筆者在這裡就不多說了。我有個同學做Asp.NET開發的。他跟我講過一句話——我都快忘了HTML了。上一章中我們知道做Asp.NET。用純HTML那麼筆者覺得你一定會被人認為是SB。對於喜歡純手工來寫界面設計的人來講,Asp.NET MVC 決對不會讓你失望。而本文筆者可能還會用到一些struts2框架的知識來比較一下。不多說了。進入本章的內容吧。
Global.asax文件在講Asp.NET MVC之前我們來看一下一個文件。就是Global.asax文件。那為什麼要講這個文件呢?而這個文件又有什麼作用呢?Global.asax文件全名為全局應用程序類。他跟Asp.NET MVC並沒有直接的關系。Asp.NET常常也會用到。想要創建他也很簡單。選中項目右擊》添加》新建項。
點擊添加按扭:
雙擊Global.asax:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; using System.Web.SessionState; namespace WebExample { public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { } protected void Session_Start(object sender, EventArgs e) { } protected void Application_BeginRequest(object sender, EventArgs e) { } protected void Application_AuthenticateRequest(object sender, EventArgs e) { } protected void Application_Error(object sender, EventArgs e) { } protected void Session_End(object sender, EventArgs e) { } protected void Application_End(object sender, EventArgs e) { } } }
看了上面的代碼。筆者相信光從名字就可能看出一二。什麼意思呢?在應用開始執行的時候會去調用Application_Start方法並且只執行一次。而每次一請求的時候會去調用Application_BeginRequest方法。當用應關團的時候,會去調用Application_End。如果做B/S開發不知道Session的話,那麼筆者也無能為力了。所以對於Session_Start方法調用,筆者就不多說了。 是不是覺得JAVA跟的Web.xml的監聽事件有一點像呢。
Asp.NET MVC筆者在學習Asp.NET MVC的時候。visual studio的Asp.NET MVC例子為筆者做了很大的貢獻。讓我們看一下visual studio的列子來了解一下Asp.NET MVC吧。什麼樣子創建項目。不用筆者在講了。直接看一下新建項目的對話框吧。
確定之後。會彈出下列對話框。
我們可以看到上面的多個選項。
空:表示建立一個什麼都沒有的Asp.NET MVC。
基本:表示建立一個最基本可以開發的Asp.NET MVC。
其他的:是面向不同業務的例子。
筆者選擇其中為Internet 應用來了解關於Asp.NET MVC的知識。下面就是新建的項目結構。
App_Data文件夾:用於存放數據文件。如SQL server的MDF文件之類似。
App_Start文件夾:這個文件夾存放了一些Asp.NET MVC開始要執行的配置類。
Content文件夾:存放一些關於主題的文件。如CSS文件。
Controllers文件夾:存放控制器。即是MVC中的C
Filters文件夾:看名字就知道存放過濾器了。
Images文件夾:不用看了。就存放圖片。
Models文件夾:用於存放模型對象。
Scripts文件夾:用於存放JS文件。
Views文件夾:用於存放視圖。
有了上面創建的列子。這對筆者相當好的一件事情。光看上面的項目結構筆者至少知道一件事情。MVC中的V就在對應的Views文件夾裡面,而C就在Controllers文件夾裡面。這對我們來講很重要。接下來就是要明白M-V-C之間是什麼樣子工作。我們就可以學習到Asp.NET MVC。Struts2在啟動的時候會去加載對應的配置文件。當然對於Asp.NET MVC來講,也有對應的這項工作。只是加載的東西不同而以。如下。
Global.asax:
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); } }
上面的代碼是在Global.asax文件裡面的。那麼筆者為什麼要哪出來講呢?這就是開始初始化Asp.NET MVC的地方。上面的總做了幾件事情呢?
1.注冊WebApi。對於WebApi是什麼。不知道大家有沒有用過RESTful 框架。可惜只是了解而以。
2.注冊過濾器。對JAVA開發人員來講,不知道過濾器。那就有一點過份了。
3.注冊路由器。這個很重要。Struts2是什麼樣子通過請求的URL來找到對應的Action類。沒有錯。一定是通過struts.xml配置文件的action節點。路由器就是相當於action節點的功能了。
4.注冊Bundle信息。關於Bundle是什麼筆者也不好說。只知道他是用於UI界面引入CSS和JS。這個時候可以把多個CSS和JS綁成一起。只要引一個Bundle的URL就是把這個些CSS和JS一起引入。
5.注冊證書。關於這個的話。請讀者們自行查看。反正筆者沒有用到過。所以不敢說。
從上面我們知道一件事情——請求的URL是通過路由器來分析找到對應的控制器。所以學習Asp.NET MVC就必須了解一下路由器是什麼樣子工作的。讓我們到App_Start文件夾裡面去找一個叫RouteConfig的類。如下
1 public class RouteConfig 2 { 3 public static void RegisterRoutes(RouteCollection routes) 4 { 5 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 6 7 routes.MapRoute( 8 name: "Default", 9 url: "{controller}/{action}/{id}", 10 defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 11 ); 12 } 13 }
上面便是配置路由器的地方。我們可以看到路由器事實是一種以設置URL模板來處理對應的URL請求。上面是每一個Asp.NET MVC都會提供的默認的URL模板。
name:當前路由器的名稱。
url:URL模板。
defaults:URL請求的默認值。
這裡跟Struts2的作法是不一樣子。Struts2在處理URL請求是通對的package節點的名字和action節點的名字來確定對應的action類,再通過action節點配置信息來執行對應的方法。而Asp.NET MVC是通過路由器來分析,並找出對應的控制器和控制器裡面的方法。什麼樣子講呢?讓我看一下上面url的值。
"{controller}/{action}/{id}"
上面就是URL模板。假設用戶請求http://xxx.xx.com.cn/aomi/index/7。通過上面的模板對應一下。我們就可以知道controller值為aomi,action值為index,id值為7。這裡id是一個可選的傳值。什麼說呢?看到id = UrlParameter.Optional了嗎?就是跟我們講id是可選的。所以嚴格來講action節點的功能跟Asp.NET MVC的控制器是對應的。都是用於控制業務結束之後要顯示的視圖。並差別是控制器是一個類。讓我們看一下控制器的代碼吧。這樣子可以加強理解。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcExample.Controllers { public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application."; return View(); } public ActionResult About() { ViewBag.Message = "Your app description page."; return View(); } public ActionResult Contact() { ViewBag.Message = "Your contact page."; return View(); } } }
我們可以知道HomeController類繼承了Controller類。是不是說繼承Controller類就可以了。顯然不是,筆者試著把HomeController後面的Controller去掉,發現根本找不到控制器。說明了Asp.NET MVC還是有一個約定——控制器要按XxxController來命名。難道就不可以讓開發人員自己來定義名字嗎?筆者沒有說不行。只是有一點煩麻。他要用到控制器工廠。即是IControllerFactory。所以筆者還是希望大家能老實一點吧。struts2在業務結束之後。會返回一個字符串結果來確定要去呈顯的視圖。struts2的視圖卻有幾種。同樣子Asp.NET MVC他也有若干個返回結果。
EmptyResult:返回一個空的結果。即是返回值為void。
ContentResult:返回一個文本內容的結果。
JsonResult:返回一個JSON格式的結果。
ViewResult:返回一個視圖的結果。即是類似於HTML文件。
上面筆者並沒有全部列出來。其他的話,筆者希望讀者們自己去查看。好了。讓我們看一下上面代碼部分中有一個View()的方法。這個返回的是一個ViewResult型類。上面只是調用View()。這個時候他會用方法名來確定對應的視圖。比如index方法被調用。那麼View()就會到Views文件夾下的Home文件夾去找Index.cshtml。那麼為什麼是Home文件夾呢?默認就是如果XxxController的話,就是View/Xxx下面找對應的視圖。那麼對於cshtml文件是什麼呢?你可以理解為跟ftl文件是一個類型的。同時在Views文件玩夾下有一個叫Shared文件夾。如下。
本來每一個控制器在Views文件夾都會有一個對應的文件夾。文件夾名跟控制器的名字一樣子。那麼有沒有共用的呢?沒有錯。Shared文件夾就是用於所有控制器供用的。現在只有一個問題了——使用其他的視圖。看一下下面的圖片。
如果我們調用Index方法。按道理我們要去調用Index.cshtml。那麼如果要調用Aomi.cshtml什麼辦。如下就可以了。
public class Home:Controller { public ActionResult Index() { return View("Aomi"); } }
我們都知道了控制器是如何去找視圖之後。我們要去了解一下View到Controller的傳值和Controller到View的傳值。
一、View到Controller的傳值。一般有倆種。一種是用模型對象來傳。一種是KEY-VALUE來傳值。但是一定要確保表單元素的Name要跟參數命名對應。即是相同。
二、Controller到View的傳值。一般有三種。用ViewBag傳值。用Model傳值。即是模型對象。還有用ViewData。
筆者增加了一個方法Aomi。然後參數為name。並通過動態類型ViewBag傳到視圖上。並顯示出來。
控制器:
public class Home:Controller { public ActionResult Index() { return View("Aomi"); } public ActionResult Aomi(string name) { ViewBag.Name = name; return View("Aomi"); } }
視圖:
@{ ViewBag.Title = "Aomi"; } <h2>@ViewBag.Name</h2>
執行結果:
注意:name一定要跟參數的命名相同。不然傳不了。
筆者簡單的講解了一下關於傳值的問題。現在我們要來看一下視圖上所用的知識。Asp.NET MVC的視圖一般都是用razor引擎。所以學習razor語法很重要。網絡上關於razor語法很多。筆者就不多說。筆者簡單的講一個例子。
public class HomeController : Controller { public ActionResult Index() { return View("Aomi"); } public ActionResult Aomi(string name) { ViewBag.Name = name; return View("Aomi"); } public ActionResult Show() { ViewBag.DataList = new List<string>() { "a", "b", "c" }; return View(); } }
Show.cshtml:
@{ ViewBag.Title = "Show"; } @foreach (string val in ViewBag.DataList) { <b>@val</b> }
執行結果:
其實學習Asp.NET MVC並不難。只要掌握以幾點,筆者相信企業開發就沒有什麼大問題。
1.了解一下路由器的用法。
2.View和Controller之間是如何傳值的。
3.Controller是如何確定View的。
4.最後就是學習razor語法。
本章總結本章主要是了解一下Asp.NET MVC。講解路由器和視圖與控制之間傳值。可以說這是重點。那麼本系列就到這裡了。本系列的目地不是為了教學。而是一個引導。是筆者當年學習C#時候的一個過程。最後謝謝大家。