譯文,個人原創,轉載請注明出處(C# 6 與 .NET Core 1.0 高級編程 - 40 章 ASP.NET Core(上)),不對的地方歡迎指出與交流。
章節出自《Professional C# 6 and .NET Core 1.0》。水平有限,各位閱讀時仔細分辨,唯望莫誤人子弟。
附英文版原文:Professional C# 6 and .NET Core 1.0 - 40 ASP.NET Core
本章節譯文分為上下篇,下篇見:C# 6 與 .NET Core 1.0 高級編程 - 40 ASP.NET Core(下)
---------------------------
本章內容
- 了解ASP.NET Core 1.0和Web技術
- 使用靜態內容
- 使用HTTP請求和應答
- 使用依賴注入與ASP.NET
- 定義自定義簡單路由
- 創建中間件組件
- 使用會話進行狀態管理
- 讀取配置設置
Wrox.com網站關於本章的源代碼下載
本章的wrox.com代碼下載位於http://www.wrox.com/go/professionalcsharp6的“下載代碼”選項卡上。本章的代碼包含此示例項目:WebSampleApp。
ASP.NET Core 1.0
ASP.NET經過15年(譯者注:第一個版本的asp.net在2002年2月發布),ASP.NET Core 1.0是一個完全重寫的ASP.NET。它具有模塊化編程的特征,完全開放源代碼,輕量級以便在雲平台得到最佳使用,並且可用於非Microsoft平台。
完全重寫ASP.NET有很多優點,但這也意味着要重新處理基於ASP.NET的舊版本的現有Web應用程序。是否有必要將現有的Web應用程序重寫到ASP.NET Core 1.0?讓我們試着回答這個問題。
ASP.NET Web窗體不再是ASP.NET Core 1.0的一部分。然而,擁有包含此技術的Web應用程序並不意味着必須重寫它們。仍然可以使用完整的框架來維護使用ASP.NET Web Forms編寫的遺留的應用程序。 甚至在最新版本的ASP.NET 4.6 中對ASP.NET Web窗體進行了增強,例如異步模型捆綁。
ASP.NET MVC仍然是ASP.NET Core 1.0的一部分。因為ASP.NET MVC 6已經完全重寫,所以您需要對使用ASP.NET MVC 5或更早版本編寫的Web應用程序進行一些更改,以將它們帶到新的應用程序堆棧。
將ASP.NET Web窗體轉換為ASP.NET MVC可能需要做很多工作。 ASP.NET Web窗體從開發者角度抽象出HTML和JavaScript。使用ASP.NET Web窗體,沒有必要知道HTML和JavaScript,而是使用帶有C#代碼的服務器端控件。服務器端控件本身返回HTML和JavaScript。這種編程模型類似於舊的Windows窗體編程模型。使用ASP.NET MVC,開發人員需要知道HTML和JavaScript。 ASP.NET MVC是基於模型 - 視圖 - 控制器(MVC)模式,這很容易進行單元測試。因為ASP.NET Web窗體和ASP.NET MVC基於截然不同的架構模式,所以將ASP.NET Web窗體應用程序遷移到ASP.NET MVC是一項巨大的工作。在進行這項任務之前,應該建立一個清單,列出使用解決方案保留舊技術的優點和缺點,並將其與使用新技術的優點和缺點進行比較。ASP.NET Web窗體還可以用來工作多年。
注意 本書編者的網站http://www.cninnoation.com最初是用ASP.NET Web窗體創建的。這個網站已經被轉換成早期版本的新技術的ASP.NET MVC。由於原來的網站已經使用了很多獨立的組件來抽象數據庫和服務代碼,它並不算是一個真正的巨大的任務,所以做得非常快。因此能夠直接從ASP.NET MVC使用數據庫和服務代碼。另一方面,如果開始使用Web窗體控件訪問數據庫而不是使用自定義的控件,這也將是一個繁雜的工作。
注意 本書不包括傳統技術的ASP.NET Web窗體。 也不包括ASP.NET MVC 5。本書重點介紹新技術,因此關於Web應用程序,材料基於ASP.NET 5和ASP.NET MVC 6。這些技術應該用於新的Web應用程序。如果需要維護較舊的應用程序,應該閱讀比本書更早的版本,如《Professional C#5.0和.NET 4.5.1》,它介紹 ASP.NET 4.5,ASP.NET Web窗體4.5和ASP.NET MVC 5 。
本章介紹了ASP.NET Core 1.0的基礎,第41章解釋了使用ASP.NET MVC 6,這是一個構建在ASP.NET Core 1.0之上的框架。
Web技術
在本章后面介紹ASP.NET的基礎之前,本節將介紹在創建Web應用程序時非常重要的核心Web技術:HTML,CSS,JavaScript和jQuery。
HTML
HTML是由Web瀏覽器解釋的標記語言。它定義元素以顯示各種標題、表、列表和輸入元素,如文本和組合框。
自2014年10月以來,HTML5一直是W3C的一項建議(http://w3.org/TR/html5),而且所有主流瀏覽器都提供支持。使用HTML5的功能,很多瀏覽器插件(例如Flash和Silverlight)已經不需要,因為加載項所做的事情現在可以直接使用HTML和JavaScript完成。當然,您可能仍需要Flash和Silverlight,因為並非所有網站都遷移到新技術,或者用戶可能仍在使用不支持HTML5的舊版瀏覽器版本。
HTML5增加了新的語義元素,搜索引擎能夠更好地用於分析網站。畫布元素允許動態使用2D形狀和圖像,視頻和音頻元素使對象元素過時。最近的媒體源產品(http://w3c.github.io/media-source)自適應流也由HTML提供,以前這是Silverlight的一個優勢。
HTML5還定義了用於拖放、存儲、Web套接字等的API。
CSS
HTML定義網頁的內容,而CSS定義外觀。例如在早期的HTML中,列表項標簽<li>定義列表元素是否應該顯示為圓形,圓盤或正方形。現在這些信息被完全從HTML中刪除,而是放入級聯樣式表(CSS)。
CSS樣式可以使用靈活的選擇器來選擇HTML元素,並且可以為這些元素定義樣式。可以通過其ID或其名稱選擇元素,還可以定義HTML代碼內的可被引用的CSS類。對於較新版本的CSS,可以定義比較復雜的規則來選擇特定的HTML元素。
從Visual Studio 2015開始,Web項目模板可以使用Twitter Bootstrap。這是一個CSS和HTML約定的集合,可以輕松適應不同的外觀和下載即用模板。有關文檔和基本模板,請訪問www.getbootstrap.com。
JavaScript和TypeScript
並非所有平台和瀏覽器都可以使用.NET代碼,但幾乎每個瀏覽器都支持JavaScript。一個對JavaScript的常見誤解是它與Java有關。事實上,只有名稱是類似的,因為Netscape(JavaScript的發起者)與Sun(Sun發明Java)達成協議,允許在名稱中使用Java。如今,這兩家公司已不再存在。 Sun被Oracle收購,現在Oracle持有Java的商標。
Java和JavaScript(和C#)都有相同的根 - C編程語言。 JavaScript是一種不是面向對象的功能性編程語言,盡管它已經添加面向對象的功能。
JavaScript允許從HTML頁面訪問文檔對象模型(DOM),這使得客戶端上可以動態更改元素。
ECMAScript是定義JavaScript語言的當前和即將到來的特性的標准。因為其他公司不允許在其語言實現中使用術語Java,所以標准名稱為ECMAScript。 Microsoft的JavaScript實現名稱是JScript。請查看http://www.ecmascript.org了解JavaScript語言的現狀和發展動態。
即使許多瀏覽器不支持最新的ECMAScript版本,但仍然可以編寫ECMAScript 5代碼。可以使用TypeScript代替編寫JavaScript代碼。 TypeScript語法基於ECMAScript,但它具有一些增強功能,例如強類型代碼和注釋。可以看到C#和TypeScript之間有很多相似之處。因為TypeScript編譯器編譯為JavaScript,所以TypeScript可以在需要JavaScript的任何地方使用。有關TypeScript的詳細信息,請訪問http://www.typescriptlang.org。
腳本庫
除了JavaScript編程語言,還需要腳本庫,來使生活更輕松(譯者注:這句話有點調侃的意味)。
- jQuery(http://www.jquery.org)是一個庫,它在訪問DOM元素並對事件做出反應時抽象出瀏覽器的差異。
- Angular(http://angularjs.org)是一個基於MVC模式的庫,用於簡化單頁Web應用程序的開發和測試。 (與ASP.NET MVC不同,Angular提供了客戶端代碼的MVC模式。)
ASP.NET Web項目模板包括jQuery庫和Bootstrap。 Visual Studio 2015支持IntelliSense和調試JavaScript代碼。
注意 本書中沒有介紹為Web應用程序設計樣式和編寫JavaScript代碼。可以在 《HTML和CSS》中閱讀更多關於HTML和樣式:John Ducket設計和構建網站(Wiley,2011),並通過Nicholas C. Zakas(Wrox,2012)為Web開發人員加快專業JavaScript技術提升。
ASP.NET Web項目
首先創建一個名為WebSampleApp的空ASP.NET Core 1.0 Web應用程序(參見圖40.1)。本章從一個空模板開始添加功能。
圖40.1
注意通過本章的示例代碼下載,需要取消注釋啟動類中的特定代碼塊來激活所討論的功能。也可以從頭開始創建項目。沒有太多的代碼可以看到所有的功能。
創建項目后,將看到一個名為WebSampleApp的解決方案和項目文件,其中包含一些文件和文件夾(參見圖40.2)。
圖40.2該解決方案包含global.json配置文件,該文件列出解決方案的目錄。可以在以下代碼段中從“projects”鍵的值查看此內容。 src目錄包含具有源代碼的解決方案的所有項目。“test”目錄用於定義單元測試,雖然它們還不存在。 sdk設置定義所使用的SDK的版本號(代碼文件global.json)。
{ "projects": ["src","test" ], "sdk": { "version":"1.0.0-0" } }
在項目結構中,使用瀏覽器打開文件Project_Readme.html時,可以看到有關ASP.NET Core 1.0的一些總體信息。在項目文件夾中可以看到一個“References”文件夾。它包含所有引用的NuGet包。對於一個空的ASP.NET Web應用程序項目,引用的軟件包僅有Microsoft.AspNetCore.IISPlatformHandler和Microsoft.AspNetCore.Server.Kestrel。
IISPlatformHandler包含IIS的模塊,用於將IIS基礎結構映射到ASP.NET Core 1.0。 Kestrel是ASP.NET Core 1.0的一個新的Web服務器,在Linux平台上也可以使用它。
還可以在project.json文件中找到NuGet包的引用。 (在以下代碼片段中,它們在“dependencies”部分。)框架部分列出了支持的.NET框架,如net452(.NET 4.5.2)和netstandard1.0(.NET Core 1.0)。可以刪除不需要托管的那個。 “exclude”部分列出了不應用於編譯應用程序的文件和目錄。“publishExclude”部分列出不應發布的文件和文件夾(代碼文件WebSampleApp/project.json):
{ "version":"1.0.0-*", "compilationOptions": { "emitEntryPoint": true }, "dependencies": { "NETStandard.Library":"1.0.0-*", "Microsoft.AspNetCore.IISPlatformHandler":"1.0.0-*", "Microsoft.AspNetCore.Server.Kestrel":"1.0.0-*" }, "frameworks": { "net452": { }, "netstandard1.0": { "dependencies": { "NETStandard.Library":"1.0.0-*" } } }, "content": ["hosting.json" ] "exclude": [ "wwwroot", "node_modules" ], "publishExclude": [ "**.user", "**.vspscc" ] }
“項目設置”中的“調試”選項可以配置使用Visual Studio開發時使用的Web服務器(請參見圖40.3)。默認情況下,IIS Express使用“調試”設置指定的端口號進行配置。 IIS Express由Internet信息服務器(IIS)派生,並提供IIS的所有核心功能。這樣在幾乎相同的環境中開發Web應用程序變得容易,在該環境中應用程序將被稍后托管(如果IIS用於托管)。
圖40.3
要使用 Kestrel 服務器運行應用程序,可以使用“調試項目”設置選擇Web配置文件。Profile選項中的可用選項列表是project.json中列出的命令。
使用Visual Studio項目設置更改的設置會影響launchSettings.json文件的配置。此文件還可以定義一些其他配置,如命令行參數(代碼文件WebSampleApp/Properties/launchsettings.json):
{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { "applicationUrl":"http://localhost:19879/", "sslPort": 0 } }, "profiles": { "IIS Express": { "commandName":"IISExpress", "launchBrowser": true, "environmentVariables": { "Hosting:Environment":"Development" } }, "web": { "commandName":"web", "launchBrowser": true, "launchUrl":"http://localhost:5000/", "commandLineArgs":"Environment=Development", "environmentVariables": { "Hosting:Environment":"Development" } } } }
解決方案資源管理器中項目結構中的“Dependencies”文件夾顯示JavaScript庫的依賴項。 創建空項目時,該文件夾為空。 本章后面的“添加靜態內容”部分添加依賴項。
“wwwroot”文件夾是需要發布到服務器的靜態文件的文件夾。 目前這個文件夾是空的,但通過這一章,可以添加HTML和CSS文件和JavaScript庫。
一個C#源文件 - Startup.cs - 也包括在一個空項目中。 接下來討論這個文件。在創建項目期間,需要這些依賴項和命名空間:
依賴項
Microsoft.AspNetCore.Http.Abstractions
Microsoft.AspNetCore.IISPlatformHandler
Microsoft.AspNetCore.Server.Kestrel
Microsoft.AspNetCore.StaticFiles
Microsoft.AspNetCore.Session
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.UserSecrets
Microsoft.Extensions.Logging
Microsoft.Extensions.Logging.Console
Microsoft.Extensions.Logging.Debug
Microsoft.Extensions.PlatformAbstractions
Newtonsoft.Json
System.Globalization
System.Text.Encodings.Web
System.Runtime
命名空間
Microsoft.AspNetCore.Builder;
Microsoft.AspNetCore.Hosting;
Microsoft.AspNetCore.Http;
Microsoft.Extensions.Configuration
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Logging
Microsoft.Extensions.PlatformAbstractions
Newtonsoft.Json
System
System.Globalization
System.Linq
System.Text
System.Text.Encodings.Web
System.Threading.Tasks
啟動
現在是時候開始從Web應用程序中獲得一些功能。 要獲取有關客戶端的信息並返回響應,需要對HttpContext寫一個響應。
在空的ASP.NET Web應用程序模板創建一個啟動類,其中包含以下代碼(代碼文件WebSampleApp/Startup.cs):
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; // etc. namespace WebSampleApp { public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { app.UseIISPlatformHandler(); // etc. app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); }); } public static void Main(string[] args) { var host = new WebHostBuilder() .UseDefaultConfiguration(args) .UseStartup<Startup>() .Build(); host.Run(); } } }
Web應用程序的入口點是 Main 方法。之前在project.json配置文件中看到的emitEntryPoint配置可以定義是否應該使用Main方法。還定義了在本書中創建的.NET Core控制台應用程序的Main方法。只有庫不需要Main方法。
使用從Visual Studio模板生成的默認實現,Web應用程序在WebHostBuilder實例的幫助下配置。WebHostBuilder將調用UseDefaultConfiguration方法。該方法接收命令行參數並創建包括可選托管文件(hosting.json)的配置,添加環境變量,並將命令行參數添加到配置。方法UseStartup定義使用Startup類,它反過來調用方法ConfigureServices和Configure。WebApplicationBuilder調用的最后一個方法是Build方法,它返回實現接口IWebApplication的對象。返回的應用程序對象調用Run方法,啟動托管引擎,現在服務器進入偵聽和等待請求狀態。hosting.json文件用於配置服務器(代碼fileWebSampleApp/hosting.json):
{ "server":"Microsoft.AspNetCore.Server.Kestrel", "server.urls":"http://localhost:5000" }
Startup類被傳遞給具有通用模板參數的UseStartup方法,然后調用ConfigureServices和Configure方法。
Configure方法通過實現接口IApplicationBuilder的依賴注入接收內部應用程序編譯器類型。該接口用於定義應用程序使用的服務。調用接口的Use方法,可以創建HTTP請求管道以定義請求的應答要做什么。Run方法是接口IApplicationBuilder的擴展方法,它調用Use方法。該方法在程序集Microsoft.AspNetCore.Http.Abstractions中的RunExtensions擴展類和命名空間Microsoft.AspNetCore.Builder實現。
Run方法的參數是RequestDelegate類型的委托。該類型接收HttpContext作為參數,並返回一個Task。HttpContext(代碼片段中的 context 變量)可以訪問瀏覽器中的請求信息(HTTP頭,Cookie和表單數據),也可以發送響應。代碼片段返回一個簡單的字符串 - Hello,World! - 到客戶端,如圖40.4所示。
圖40.4
注意 如果使用Microsoft Edge測試Web應用程序,則需要啟用localhost。在地址欄中鍵入about:flags,並啟用“允許本地主機環回”選項(見圖40.5)。不僅可以使用Microsoft Edge的內置用戶界面來設置此選項,還可以使用命令行選項:實用程序CheckNetIsolation。命令 “CheckNetIsolation LoopbackExempt -a - n = Microsoft.MicrosoftEdge_8wekyb3d8bbwe”啟用本地主機類似於為Microsoft Edge使用更友好的用戶界面。如果要配置其他Windows應用程序以允許localhost,則實用程序CheckNetIsolation非常有用。
圖40.5
將日志信息添加到Web應用程序對獲取更多的信息是非常有用的,能夠了解發生了什么。為了達到這個目的,Startup 類的Configure方法接收ILoggerFactory對象。該接口可以使用AddProvider方法添加日志提供程序,並使用CreateLogger方法創建一個實現ILogger接口的日志程序。以下代碼段中顯示的AddConsole和AddDebug方法是用於添加不同提供程序的擴展方法。 AddConsole方法添加一個提供程序負責將日志信息寫入控制台,AddDebug方法添加一個提供程序負責將日志信息寫入調試程序。這兩種方法不傳遞參數值,默認值用於配置日志消息。默認值指定為寫入信息的日志消息類型或者更高級別。可以用不同的重載來指定其他用於記錄的過濾項,或者可以使用配置文件配置日志記錄(代碼文件WebSampleApp/Startup.cs):
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { // etc. loggerFactory.AddConsole(); loggerFactory.AddDebug(); // etc. }
ILogger接口可以在 Log 方法中編寫自定義日志信息。
添加靜態內容
通常不會只是發送簡單的字符串到客戶端。 默認情況下,無法發送簡單的HTML文件和其他靜態內容。 因為ASP.NET 5會盡可能減少開銷。 如果不啟用它們,不會從服務器返回靜態文件。
要啟用從Web服務器提供的靜態文件,可以添加擴展方法UseStaticFiles(並注釋先前創建的Run方法):
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { app.UseiISPlatformHandler(); app.UseStaticFiles(); //etc. }
只要將相同大小寫的代碼行添加到Configure方法中,編輯器中的智能標記就會添加NuGet包Microsoft.AspNet.StaticFiles。 選中該項,NuGet包下載並在project.json中列出:
"dependencies": { "Microsoft.AspNetCore.IISPlatformHandler":"1.0.0-*", "Microsoft.AspNetCore.Server.Kestrel":"1.0.0-*", "Microsoft.AspNetCore.StaticFiles":"1.0.0-*" },
添加靜態文件的文件夾是項目中的“wwwroot”文件夾。 可以使用webroot設置來配置 project.json 文件中的文件夾的名稱。 如果沒有配置文件夾,默認是“wwwroot”。 通過添加配置添加NuGet包,可以將HTML文件添加到wwwroot文件夾(代碼文件WebSampleApp/wwwroot/Hello.html),如下所示:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <h1>Hello, ASP.NET with Static Files</h1> </body> </html>
啟動服務器之后,從瀏覽器發出對HTML文件的請求,例如 http://localhost:5000/Hello.html 。根據配置,端口號可能因項目而異。
注意 在使用ASP.NET MVC創建Web應用程序時,還需要了解HTML,CSS,JavaScript和一些JavaScript庫。由於本書的重點是C#和.NET,這些主題的內容保持在最低限度。編者只是談及ASP.NET MVC和Visual Studio需要知道的最重要的任務。
使用JavaScript包管理器:npm
對於Web應用程序,通常需要一些JavaScript庫。在Visual Studio 2015之前,JavaScript庫可用作NuGet包 - 類似於.NET程序集作為NuGet包使用。因為腳本庫周圍的社區通常不使用NuGet服務器,他們也不創建NuGet包。從Microsoft或Microsoft友好社區為JavaScript庫創建NuGet包需要額外的工作。因此JavaScript周圍的社區使用具有類似於NuGet的功能的服務器而不是使用NuGet。
節點包管理器(npm)是JavaScript庫的包管理器。最初來自Node.Js(用於服務器端開發的JavaScript庫),npm對服務器端腳本很強大。然而,越來越多的客戶端腳本庫也可以與npm一起使用。
Visual Studio 2015 可以通過從項目模板添加NPM配置文件,將npm添加到項目。添加項目模板時,package.json文件將添加到項目中:
{ "version":"1.0.0", "name":"ASP.NET", "private":"true", "devDependencies": { } }
在Visual Studio中打開文件后,可以在編輯器中看到npm標志,如圖40.6所示。
圖40.6
注意 單擊“顯示所有文件”按鈕時,解決方案資源管理器中才會顯示package.json文件。
當向此文件的devDependencies部分添加JavaScript庫,在鍵入時將連接npm服務器以允許完成JavaScript庫,並顯示可用的版本號。在編輯器中選擇版本號時,還可以獲得^和~的前綴。如果沒有前綴,從服務器檢索鍵入的確切名稱的庫的版本。^前綴檢索相同主版本號的最新庫,〜前綴檢索具有相同次要版本號的最新庫。下面的package.json文件引用了幾個gulp庫和rimraf庫。保存package.json文件時,將從服務器加載npm軟件包。在解決方案資源管理器中,可以在“依賴關系”部分中查看npm加載的庫。 Dependencies部分有一個npm子節點,其中顯示所有已加載的庫。
{ "version":"1.0.0", "name":"ASP.NET", "private":"true", "devDependencies": { "gulp":"3.9.0", "gulp-concat":"2.6.0", "gulp-cssmin":"0.1.7", "gulp-uglify":"1.2.0", "rimraf":"2.4.2" } }
這些JavaScript庫引用有什么用? gulp是一個編譯系統,將在下一節中討論。 gulp-concat連接JavaScript文件;gulp-cssmin最小化CSS文件;gulp-uglify縮小JavaScript文件;而rimraf允許刪除層次結構中的文件,minification 刪除所有不必要的字符。
添加軟件包后,可以使用解決方案資源管理器中“依賴項”部分中的npm節點輕松地更新或卸載軟件包。
使用gulp編譯
Gulp是JavaScript的編譯系統。npm類似於NuGet,而 gulp 類似於.NET開發實用程序(DNU)。既然 JavaScript代碼被解析,為什么還需要一個使用JavaScript的編譯系統?在將HTML,CSS和JavaScript這些文件放到服務器上之前,有很多工作要做。編譯系統可以將Syntactically Awesome Stylesheets(SASS)文件(具有腳本功能的CSS)轉換為CSS,同時可以縮小和壓縮文件,還可以啟動腳本的單元測試,並且可以分析JavaScript代碼(例如, JSHint) - 有很多有用的任務可以做。
用npm添加gulp之后,可以使用Visual Studio項目模板添加"Gulp Configuration File"。此模板創建以下gulp文件(代碼文件MVCSampleApp/gulpfile.js):
/* This file is the main entry point for defining Gulp tasks and using Gulp plugins. Click here to learn more. http://go.microsoft.com/fwlink/?LinkId=518007 */ var gulp = require('gulp'); gulp.task('default', function () { // place code for your default task here });
帶有gulp標志的編輯器如圖40.7所示。
圖40.7
現在在gulp文件中添加一些任務。 第一行定義此文件的所需庫,並將變量分配給腳本。 這里已經添加了npm的庫被會使用。 gulp.task函數創建gulp任務,可以使用Visual Studio任務運行器瀏覽器啟動:
"use strict"; var gulp = require("gulp"), rimraf = require("rimraf"), concat = require("gulp-concat"), cssmin = require("gulp-cssmin"), uglify = require("gulp-uglify") var paths = { webroot:"./wwwroot/" }; paths.js = paths.webroot +"js/**/*.js"; paths.minJs = paths.webroot +"js/**/*.min.js"; paths.css = paths.webroot +"css/**/*.css"; paths.minCss = paths.webroot +"css/**/*.min.css"; paths.concatJsDest = paths.webroot +"js/site.min.js"; paths.concatCssDest = paths.webroot +"css/site.min.css"; gulp.task("clean:js", function (cb) { rimraf(paths.concatJsDest, cb); }); gulp.task("clean:css", function (cb) { rimraf(paths.concatCssDest, cb); }); gulp.task("clean", ["clean:js","clean:css"]); gulp.task("min:js", function () { gulp.src([paths.js,"!" + paths.minJs], { base:"." }) .pipe(concat(paths.concatJsDest)) .pipe(uglify()) .pipe(gulp.dest(".")); }); gulp.task("min:css", function () { gulp.src([paths.css,"!" + paths.minCss]) .pipe(concat(paths.concatCssDest)) .pipe(cssmin()) .pipe(gulp.dest(".")); }); gulp.task("min", ["min:js","min:css"]);
Visual Studio 2015為gulp文件提供了一個任務運行器瀏覽器(見圖40.8)。雙擊任務以啟動它。還可以將gulp任務映射到Visual Studio命令。這樣,當打開項目時,在編譯之前或之后,或者當在“編譯”菜單中選擇了“清理”菜單項時,gulp任務將自動啟動。
圖40.8
注意 Visual Studio支持的另一個JavaScript編譯系統是Grunt。 Grunt的重點是通過配置來編譯,而Gulp的重點是通過JavaScript代碼編譯。
使用Bower客戶端庫
大多數客戶端的 JavaScript庫都通過 Bower 使用。 Bower是一個像 npm 的軟件包管理器。而 npm 項目從服務器端代碼的JavaScript庫開始(盡管許多客戶端腳本庫也可以使用npm),Bower提供了成千上萬的JavaScript客戶端庫。Bower可以通過使用項目模板 “Bower Configuration File”添加到ASP.NET Web項目。該模板添加的文件bower.json如下所示:
{ "name":"ASP.NET", "private": true, "dependencies": { } }
向項目添加Bower還會添加配置Bower的.bowerrc文件。 默認情況下,使用目錄設置時腳本文件(以及腳本庫附帶的CSS和HTML文件)將復制到wwwroot/lib目錄:
{ "directory":"wwwroot/lib" }
注意 與NPM類似,單擊解決方案資源管理器中的“顯示所有文件”按鈕,才能查看與bower相關的文件。
Visual Studio 2015對Bower有特殊支持。 圖40.9顯示了編輯器中的Bower圖標。
圖40.9
向bower.json文件添加腳本庫,可以通過鍵入庫的名稱和版本號獲得IntelliSense。 與npm類似,保存文件時將從服務器檢索庫,並且可以在Dependencies文件夾中找到它們。 由於.bowerrc中的配置,腳本庫中的文件被復制到wwwroot/lib文件夾(代碼文件MVCSampleApp/.bowerrc):
{ "name":"ASP.NET", "private": true, "dependencies": { "bootstrap":"3.3.5", "jquery":"2.1.4", "jquery-validation":"1.14.0", "jquery-validation-unobtrusive":"3.2.5" } }
通過單擊應用程序上下文菜單“Manage Bower Packages”,可以訪問的“Manage Bower Packages”工具管理Bower軟件包。這個工具非常類似於NuGet包管理器,使管理Bower軟件包變得輕松(見圖40.10)。
圖40.10
基礎設施已經就位,現在是時候進入HTTP請求與應答了。