這篇文章是從我的 github 博客 http://lxconan.github.io 導入的。
如果你想用 ASP.NET MVC 創建一個網絡應用,那么你可以搜到很多的文章。但是沒有多少文章告訴你,如何從零開始創建一個 ASP.NET MVC 應用程序。這對我們是非常有害的,我們希望了解每一個細節,搞清 Components 之間的聯系。然后,再放心的使用向導創建 ASP.NET MVC 應用程序。需要表明一點的是,我說的從零開始,是從零開始一步一步創建 App,我希望你應該熟悉 C#,并至少對 ASP.NET MVC 多多少少有些了解。
我們將使用 ASP.NET MVC 5,因此請至少準備好一個支持 .NET 4.5 的 Visual Studio 版本(2012 或者 2013)。如果沒有銀子購買專業版或者以上版本,那么用免費的 Express 版本也是不錯的。
首先我們要創建一個空白的 Web Application。打開 visual studio 并創建一個空白的 Web Application。為了照顧新同學我大發善心的告訴你,應該選擇 ASP.NET Empty Web Application
。微軟會非常友好的添加一大堆你可能一輩子都用不著的程序集引用。因此我們第一件事兒就是刪掉他們。刪到如下程度為止:
Solution
|-Homework.App
|-Properties
| |-AssemblyInfo.cs
|-References
| |-System
| |-System.Core
|-Web.config
安裝 ASP.NET MVC 5 Packages
在前幾個 ASP.NET MVC 版本的時候,你需要從官方網站上下個包,然后點 Setup 然后……總之一切都顯得有點兒不專業,好在現在不用了。打開 nuget manager ,安裝 Microsoft ASP.NET MVC
,或者在 package management console 里面輸入:
Install-Package Microsoft.AspNet.Mvc -Version 5.0.0
這個 package 會安裝以下三個依賴包:Microsoft ASP.NET Razor
、Microsoft ASP.NET Web Pages
以及 Microsoft Web Infrastructure
。以下的東西不用記,如果有興趣,你可以當看小說似的看一下:
- 其中第一個包是 ASP.NET MVC 的 Razor 的語言解析器,用于將 .cshtml 的服務端頁面解析為抽象語法樹,并提供編輯器支持。
- 第二個包,也就是
ASP.NET Web Pages
,提供了 ASP.NET MVC 服務端頁面編輯需要的各種輔助工具。- 例如,防止 XSS 和 CSRF 攻擊的輔助類型(參見
System.Web.Helpers
、System.Web.Helpers.AntiXsrf
名字空間) - Model 的客戶端驗證類型(就是類似“必須填寫”,“必須在xxx范圍之內”這種東西,當然,我對這些東西不抱有好感),以及最基本的 HTML 元素輸出的支持(
TagBuilder
,這可是個好同志,如果你不用他書寫自己的HtmlHelper
擴展方法,而是還在用string.Format()
輸出 HTML,那么,快去改掉那些該死的代碼)。這些都在System.Web.Mvc
名字空間里。 - 服務端頁面的基本類型:
WebPageBase
。你可能驚訝的發現了一個名為WebPage
的類型,并且里面還有Model
,Layout
等你耳熟能詳的屬性,你興奮的以為你找到了組織但是我只能告訴你你搞錯了。這個WebPage
真的是一坨 Rubbish。真正的 ASP.NET MVC WebPage 在System.Web.Mvc.WebViewPage
里,這是一個為了向下兼容而遺留下來的歷史問題。 - Razor 服務端頁面的編譯邏輯(在
System.Web.WebPages.Razor
里)。 - 一些好用的和過時了的頁面輔助類型(請看
System.Web.Helpers
)。這里加入我的個人吐槽,如果你以后創建了一個 Framework,那么千萬不要把輔助類加到你的 Framework 的包中,而是當作一個附加的包供大家自由下載使用。否則為了向后兼容性你不得不讓這些丑陋的設計一直存在下去,并被持續吐槽。
- 例如,防止 XSS 和 CSRF 攻擊的輔助類型(參見
- 第三個包,也就是
Microsoft Web Infrastructure
提供了 ASP.NET 的基礎架構——才怪!里面充斥了對反射功能的封裝(服務端頁面需要這些特性)和系統環境的檢查(例如注冊表)。總之,加上它,ASP.NET MVC 需要它,但是我們不會使用它。
安裝好以后我們的工程看起來貌似有些料了:
Solution
|-Homework.App
|-Properties
| |-AssemblyInfo.cs
|-References
| |-Microsoft.Web.Infrastructure
| |-System
| |-System.Core
| |-System.Web.Helpers
| |-System.Web.Mvc
| |-System.Web.Razor
| |-System.Web.WebPages
| |-System.Web.WebPages.Deployment
| |-System.Web.WebPages.Razor
|-Web.config
創建基本工程結構
Convension over configuration 是目前大家偏好的設計形式,Rails 在這方面非常典型,其他的 MVC Framework 也在這樣做。那么我們就按照這種約定創建工程結構吧。
- 首先我們需要一個 Controllers 名字空間來存放(默認 Area,我們以后會涉及 Area 這個概念) 下面的 Controllers 類型;
- 另外我們需要一個 Views 文件夾來存放服務端頁面。
像這樣:
Solution
|-Homework.App
|-Properties
| |-AssemblyInfo.cs
|-References
| |-Microsoft.Web.Infrastructure
| |-System
| |-System.Core
| |-System.Web.Helpers
| |-System.Web.Mvc
| |-System.Web.Razor
| |-System.Web.WebPages
| |-System.Web.WebPages.Deployment
| |-System.Web.WebPages.Razor
|-Controllers
|-Views
|-Web.config
Hello World
看標題你就知道激動人心的時刻即將來臨了。讓我們開始最后的沖刺吧。我們要添加一個 HomeController,然后添加一個 View,View 上書寫著不變的咒語:Hello World。
這個過程網絡上的文章多如牛毛,我就簡述了,總之你應該得到如下的工程結構:
Solution
|-Homework.App
|-Properties
| |-AssemblyInfo.cs
|-References
| |-Microsoft.Web.Infrastructure
| |-System
| |-System.Core
| |-System.Web.Helpers
| |-System.Web.Mvc
| |-System.Web.Razor
| |-System.Web.WebPages
| |-System.Web.WebPages.Deployment
| |-System.Web.WebPages.Razor
|-Controllers
| |-HomeController.cs
|-Views
| |-Home
| |-Index.cshtml
|-Global.asax
| |-Global.asax.cs
|-Web.config
以上的內容我認為唯一可能出問題的就是如何創建 Global.asax
文件,單擊右鍵,選擇創建 Glboal Application Class
就可以了。
下面我們簡單過一下新添加的文件的內容。其中,Index.cshtml 中的內容應該是類似這樣的:
@inherits System.Web.Mvc.WebViewPage
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
這里我們有必要解釋幾句。第一行,也就是 @inherits System.Web.Mvc.WebViewPage
這句話描述了當前頁面的類型是 System.Web.Mvc.WebViewPage
。我們之前說到了,所有的 ASP.NET MVC 頁面的基礎類型是 WebPage
,而 WebViewPage
是 WebPage
的一個派生類,他提供了 MVC 的頁面需要的所有方法和屬性,例如 Model
屬性,Html
屬性,Layout
屬性。
第二行,也就是 @{ Layout = null; }
這一行,說明了我們這個服務端頁面的所有布局信息都在這里,沒有母板頁的影響。關于 Layout
我們后續文章會有涉及。
接下來我們看看 HomeController
,它里面的內容是這樣的。
using System.Web.Mvc;
namespace Homework.App.Controllers
{
[RoutePrefix("home")]
public class HomeController : Controller
{
[Route("")]
public ActionResult Index()
{
return View();
}
}
}
HomeController
類中僅僅包含一個 GET
方法 Index()
他直接返回了 View()
這樣,ASP.NET MVC 將依據 Home/Index.cshtml
的內容生成頁面并返回給客戶端。
哦,我敢肯定你發現了什么不同:[RoutePrefix]
和 [Route]
是個什么東西,原來的 Route
不是需要用 RouteCollection.MapRoute()
方法注冊嗎?漂亮!這是 ASP.NET MVC 5 提供的新特性(從 sinatra 抄過來的,不過我一點沒有鄙夷的意思,因為 ASP.NET MVC 在不斷的改進。大家一直都在互相抄,當一個新的語言或者 Framework 形成的時候,大家做的第一件事情就是把我們在其他語言和 Framework 上做的工作完完整整的重新抄一遍)。
問題是,原來我們需要在 Web 應用程序啟動的時候使用 RouteTable.Routes.MapRoute()
指定路由的模版,那么現在要怎么做呢?請打開 Global.asax.cs
文件,刪掉那些不用的方法,只留下如下的內容。
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace Homework.App
{
public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapMvcAttributeRoutes();
}
}
}
Application_Start
方法會在應用程序啟動的時候調用,而其中的 RouteTable.Routes.MapMvcAttributeRoutes();
就是在聲明我們將使用 Attribute
進行路由的解析。
你是否迫不及待的按下了 Ctrl + F5 并且看到了期待已久的 Hello World?恭喜你!在下一節中我們將討論一些 web.config 的配置的問題。
文章列表