此教程將討論ASP.NET MVC 4 Web應用程序裏的移動特性。對於此教程,可使用 Visual Studio Express 2012 或者 Visual Web Developer 2010 Express Service Pack 1 ("Visual Web Developer 或者 VWD"). 若是你已經有了專業版本的 Visual Studio 你也可使用。css
開始以前,確保你已經安裝瞭如下列出的必需項。html
你還須要一個移動瀏覽器模擬器。下面哪一個都行:html5
本文配套的C#源代碼的Visual Studio 工程文件見下:jquery
在初學者工程中提供的簡單會議列表程序裏添加移動特性。 下面的截圖演示了在Windows 7 Phone Emulator裏看到的完整程序的頁籤。要簡化鍵盤輸入,見 Keyboard Mapping for Windows Phone Emulator 。css3
你能夠經過設置用戶代理字符串在IE9或10,FireFox或Chrome裏開發你的移動應用程序。下圖演示使用IE來模擬iPhone的完整教程。能夠用IE F-12開發者工具和 Fiddler tool 來幫你調試程序。web
如下是你將要學到的東西:express
viewport
屬性和自適應呈現來改善移動設備上的顯示效果。點擊此連接下載初學者工程的會議列表程序。而後在Windows資源管理器中,右擊 MvcMobile.zip 文件並選擇屬性。在 MvcMobile.zip 屬性對話框中,點擊「解除鎖定」按鈕。(解除鎖定防止你在使用從網上下載的.zip文件時彈出安全警告)瀏覽器
解壓 MvcMobile.zip 文件並在Visual Studio中打開 MvcMobile.sln 文件。緩存
按下 CTRL+F5 運行程序,它將顯示在桌面瀏覽器中。啓動移動瀏覽器模擬器,複製會議程序的URL到模擬器中,而後點擊 Browse by tag 連接。若是你用的是 Windows Phone 模擬器,在URL框中點擊,按下暫停(Pause)鍵獲取鍵盤訪問。下圖演示 AllTags 視圖 (點擊了 Browse by tag)。安全
這個頁面在移動設備上很是具有可讀性。點擊 ASP.NET 連接。
ASP.NET 標籤頁很是雜亂。例如Date列就很難看。接下來的教程裏會教你們建立專門爲移動瀏覽器定製的版本,那個看起來就好看多了。
注意: 目前移動緩存引擎裏有個Bug。在運行產品程序前,要先安裝 Fixed DisplayModes nugget 包。Bug的修復詳見 ASP.NET MVC 4 Mobile Caching Bug Fixed 。
CSS 媒體查詢 是對媒體類型的CSS擴展。它們能讓你爲特定的瀏覽器(用戶代理)重寫默認的CSS規則。一個常見的用於移動瀏覽器的CSS規則是定義屏幕的最大大小。 建立完ASP.NET MVC 4 Internet工程後,Content\Site.css 文件包含了如下媒體查詢:
@media only screen and (max-width: 850px) {
若是瀏覽器窗口寬度是 850 像素或更小,那它將會使用這個媒體塊中的CSS規則。像這樣使用CSS媒體查詢爲小屏幕瀏覽器(如移動瀏覽器)提供更好的HTML顯示內容,默認的CSS規則用於桌面瀏覽器的較寬顯示設計。
大多數移動瀏覽器都定義了虛擬的瀏覽器窗口寬度(視口viewport),這個寬度比移動設備的真是寬度要大得多。這使得移動瀏覽器在虛擬顯示內適應整個網頁。用戶就能夠在感興趣的內容上放大。可是,若是將視口寬度設爲實際的設備寬度的話,是不須要放大的,由於內容已經適應移動瀏覽器了。
ASP.NET MVC 4佈局文件中的viewport <meta>
標籤將視口設置成設備的寬度。
<metaname="viewport"content="width=device-width">
在編輯器中打開 Views\Shared\_Layout.cshtml 文件,把 viewport <meta>
標籤註釋掉。
@*<metaname="viewport"content="width=device-width">*@
在編輯器中打開 MvcMobile\Content\Site.css 文件,將媒體查詢中的最大寬度改成0像素。這將會防止CSS規則用在移動瀏覽器中。
@media only screen and (max-width: 0px) { ...
保存設置並在移動瀏覽器模擬器中瀏覽會議程序。下圖中的小文字就是移除viewport <meta>
標籤後的結果。沒有 viewport <meta>
標籤,瀏覽器縮小到默認視口寬度 (大多數移動瀏覽器是850 像素或更寬)
撤銷更改——在佈局文件中取消註釋 viewport <meta>
標籤並將Site.css文件中的媒體查詢恢復爲850像素。保存更改,刷新移動瀏覽器驗證一下移動友好顯示是否已恢復。
viewport <meta>
標籤和 CSS 媒體查詢並非ASP.NET MVC 4特有的,你能夠在任何web程序中利用這些特性。不過在建立新的ASP.NET MVC 4工程時,它們如今已經嵌入到生成的文件中了。
要了解更多關於 viewport <meta>
標籤,參見 A tale of two viewports — part two.
下一節,你將看到如何提供移動瀏覽器特有視圖。
ASP.NET MVC 4的一個重要新特性是能夠爲通用的移動瀏覽器、個別移動瀏覽器或者任何特定瀏覽器重寫任何視圖(包括佈局和部分視圖)的機制。要提供特定移動視圖,能夠複製一個視圖文件並在文件名中添加.Mobile。例如,要建立一個移動索引視圖,能夠複製 Views\Home\Index.cshtml 到 Views\Home\Index.Mobile.cshtml。
本節將建立一個特定移動佈局文件。
開始前,先複製 Views\Shared\_Layout.cshtml 到 Views\Shared\_Layout.Mobile.cshtml。打開 _Layout.Mobile.cshtml 並把標題從 MVC4 Conference 改成 Conference (Mobile).
在每個 Html.ActionLink
調用處,移除每個ActionLink連接裏的 "Browse by" 。下面代碼演示完整的移動佈局文件體。
<!DOCTYPE html><html><head> <metacharset="utf-8"/> <metaname="viewport"content="width=device-width"/> <title>@ViewBag.Title</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head><body> <divid="title"> <h1> Conference (Mobile)</h1> </div> <divid="menucontainer"> <ulid="menu"> <li>@Html.ActionLink("Home", "Index", "Home")</li> <li>@Html.ActionLink("Date", "AllDates", "Home")</li> <li>@Html.ActionLink("Speaker", "AllSpeakers", "Home")</li> <li>@Html.ActionLink("Tag", "AllTags", "Home")</li> </ul> </div> @RenderBody() @Scripts.Render("~/bundles/jquery") @RenderSection("scripts", required: false) </body></html>
複製 Views\Home\AllTags.cshtml 文件到 Views\Home\AllTags.Mobile.cshtml。打開新文件並將<h2>
元素從「Tags」更改成 "Tags (M)":
<h2>Tags (M)</h2>
用桌面瀏覽器和移動瀏覽器模擬器分別瀏覽該標籤頁。移動瀏覽器模擬器顯示出了這兩處更改。
相反,桌面顯示沒任何變化。
除了特定移動和特定桌面視圖,還能夠建立個別瀏覽器視圖。例如,能夠建立專用於iPhone瀏覽器的視圖。本節將建立一個用於iPhone瀏覽器和AllTags視圖的iPhone版本佈局。
打開 Global.asax 文件添加如下代碼到 Application_Start
方法。
DisplayModeProvider.Instance.Modes.Insert(0,newDefaultDisplayMode("iPhone"){ ContextCondition=(context => context.GetOverriddenUserAgent().IndexOf ("iPhone",StringComparison.OrdinalIgnoreCase)>=0)});
這段代碼定義了一個新的顯示模式,名爲iPhone,它將匹配每個傳入的請求。若是傳入的請求與你定義的條件相匹配(也就是,若是用戶代理包含了字符串」iPhone「), ASP.NET MVC 將尋找名字包含」iPhone「後綴的視圖。
在代碼裏,右擊 DefaultDisplayMode
,選擇」解析「,而後選擇 using System.Web.WebPages;
. 將添加 System.Web.WebPages
命名空間,就是 DisplayModes
和DefaultDisplayMode
類定義的地方。
另外,能夠手工添加下面的 using
部分。
usingSystem.Web.WebPages;
完整的 Global.asax 文件內容見下:
usingSystem;usingSystem.Web.Http;usingSystem.Web.Mvc;usingSystem.Web.Optimization;usingSystem.Web.Routing;usingSystem.Web.WebPages;namespaceMvcMobile{ publicclassMvcApplication:System.Web.HttpApplication { protectedvoidApplication_Start() { DisplayModeProvider.Instance.Modes.Insert(0,newDefaultDisplayMode("iPhone") { ContextCondition=(context => context.GetOverriddenUserAgent().IndexOf ("iPhone",StringComparison.OrdinalIgnoreCase)>=0) }); AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } }}
保存更改。複製 MvcMobile\Views\Shared\_Layout.Mobile.cshtml 文件到 MvcMobile\Views\Shared\_Layout.iPhone.cshtml。打開新文件並把 h1
頭從 Conference (Mobile)
改成 Conference (iPhone)。
複製 MvcMobile\Views\Home\AllTags.Mobile.cshtml 文件到 MvcMobile\Views\Home\AllTags.iPhone.cshtml。在新文件裏,把 <h2>
元素裏的 "Tags (M)" 改成 "Tags (iPhone)".
運行程序。運行移動瀏覽器模擬器,確保用戶代理設爲」iPhone「,瀏覽到 AllTags 視圖。下面的截圖顯示Safari瀏覽器裏呈現的 AllTags 視圖。你能夠在這裏下載 Safari for Windows 。
本節咱們看到了如何建立移動佈局和視圖和如何建立特定設備的佈局視圖,如iPhone。下節來討論jQuery Mobile如何控制移動視圖。
jQuery Mobile 類庫提供了一個能夠運行在全部主要移動瀏覽器的用戶接口框架。 jQuery Mobile 應用了支持CSS和JavaScript的逐步加強。逐步加強容許全部瀏覽器顯示網頁的基本內容,同時容許更多強大的瀏覽器和設備具備更豐富的顯示。jQuery Mobile包括的JavaScript 和CSS 文件不用更改任何標記就能使得元素具備適應移動瀏覽器的樣式。
本節將安裝 jQuery.Mobile.MVC NuGet 包, 它將安裝 jQuery Mobile 和 視圖開關小工具。
開始以前,先刪除以前建立的 Shared\_Layout.Mobile.cshtml 和 Shared\_Layout.iPhone.cshtml 文件。
重命名 Views\Home\AllTags.Mobile.cshtml 和 Views\Home\AllTags.iPhone.cshtml 文件爲 Views\Home\AllTags.iPhone.cshtml.hide 和 Views\Home\AllTags.Mobile.cshtml.hide.。因爲文件已經再也不有.cshtml 擴展名,因此他們不會被 ASP.NET MVC 運行時使用來呈現 AllTags 視圖。
按以下說明安裝 jQuery.Mobile.MVC NuGet 包:
從」工具「菜單,選擇」庫程序包管理器「,而後選擇」程序包管理器控制檯「。
在」程序包管理器控制檯「中,輸入 Install-Package jQuery.Mobile.MVC -version 1.0.0
下圖顯示MvcMobile工程裏由NuGet jQuery.Mobile.MVC包增長和更改的文件。增長的文件在文件名後有一個 [add] 。圖裏沒有顯示Content\images文件夾裏新增的GIF 和 PNG 文件。
jQuery.Mobile.MVC NuGet 包安裝瞭如下的東西:
ViewSwitcher
控制器小工具 (Controllers\ViewSwitcherController.cs)。打開 Global.asax 文件,在 Application_Start
方法最後加上這句代碼:
BundleMobileConfig.RegisterBundles(BundleTable.Bundles);
如下是完整的 Global.asax 文件。
usingSystem;usingSystem.Web.Http;usingSystem.Web.Mvc;usingSystem.Web.Optimization;usingSystem.Web.Routing;usingSystem.Web.WebPages;namespaceMvcMobile{ publicclassMvcApplication:System.Web.HttpApplication { protectedvoidApplication_Start() { DisplayModeProvider.Instance.Modes.Insert(0,newDefaultDisplayMode("iPhone") { ContextCondition=(context => context.GetOverriddenUserAgent().IndexOf ("iPhone",StringComparison.OrdinalIgnoreCase)>=0) }); AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); BundleMobileConfig.RegisterBundles(BundleTable.Bundles); } }}
打開 MvcMobile\Views\Shared\_Layout.Mobile.cshtml 文件,在Html.Partial調用以後直接加上下面的標記:
<divdata-role="header"align="center"> @Html.ActionLink("Home", "Index", "Home") @Html.ActionLink("Date", "AllDates") @Html.ActionLink("Speaker", "AllSpeakers") @Html.ActionLink("Tag", "AllTags") </div>
完整的 MvcMobile\Views\Shared\_Layout.Mobile.cshtml 文件:
<!DOCTYPE html><html><head> <metacharset="utf-8"/> <title>@ViewBag.Title</title> <metaname="viewport"content="width=device-width"/> @Styles.Render("~/Content/Mobile/css", "~/Content/jquerymobile/css") @Scripts.Render("~/bundles/jquery", "~/bundles/jquerymobile") </head><body> <divdata-role="page"data-theme="a"> @Html.Partial("_ViewSwitcher") <divdata-role="header"align="center"> @Html.ActionLink("Home", "Index", "Home") @Html.ActionLink("Date", "AllDates") @Html.ActionLink("Speaker", "AllSpeakers") @Html.ActionLink("Tag", "AllTags") </div> <divdata-role="header"> <h1>@ViewBag.Title</h1> </div> <divdata-role="content"> @RenderSection("featured", false) @RenderBody() </div> </div></body></html>
生成程序,在瀏覽器模擬器裏瀏覽 AllTags 視圖,如圖:
注意:能夠經過 設置用戶代理字符串 爲IE或Chrome調試移動特定代碼,而後使用 F-12開發工具。若是移動瀏覽器不顯示 Home, Speaker, Tag, 和 Date 連接的話,那麼 jQuery Mobile 腳本和 CSS 文件可能沒有正確的引用。
除了樣式變了以外,還能夠看到顯示了移動視圖和一個能讓你從移動視圖換成桌面視圖的連接。選擇Desktop視圖連接,則桌面視圖將顯示。
桌面視圖並非直接回退到移動視圖。如今就修復它吧。打開 Views\Shared\_Layout.cshtml 文件,在頁面的 body
元素下,增長如下代碼,呈現視圖開關小工具。
@Html.Partial("_ViewSwitcher")
在移動瀏覽器中刷新 AllTags 視圖。如今就能夠在桌面和移動視圖間切換了。
else{ @:NotMobile/Get}再在 Views\Shared\_Layout.cshtml 文件里加上這個頭:
<h1> Non Mobile Layout MVC4 Conference </h1>
在桌面瀏覽器裏瀏覽 AllTags 頁面。 視圖開關小工具並不在桌面瀏覽器中顯示,由於它只在移動佈局頁面纔會添加。待會兒你將看到如何將視圖開關小工具加到桌面視圖中。
在移動瀏覽器中,選擇 Speakers 連接。因爲沒有移動視圖(AllSpeakers.Mobile.cshtml),因此默認的演講者顯示界面 (AllSpeakers.cshtml) 用移動佈局視圖來呈現 (_Layout.Mobile.cshtml)。
能夠在Views\_ViewStart.cshtml文件中經過設置 RequireConsistentDisplayMode
爲 true
來全局地禁用默認(非移動)視圖呈如今移動佈局中。如:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
DisplayModeProvider.Instance.RequireConsistentDisplayMode = true;
}
當 RequireConsistentDisplayMode
設置爲 true
,移動佈局 (_Layout.Mobile.cshtml) 只用於移動視圖。 (也就是說,視圖文件名形如 ViewName.Mobile.cshtml.) 若是移動佈局在非移動視圖中顯示很差,你可能就要設置 RequireConsistentDisplayMode
爲 true
。下面的截圖演示當 RequireConsistentDisplayMode
設爲 true
時Speakers頁的樣子。
能夠在視圖文件裏經過設置 RequireConsistentDisplayMode
爲 false
來禁用視圖中的連續顯示模式。下面的標記位於 Views\Home\AllSpeakers.cshtml 文件中, RequireConsistentDisplayMode
設爲 false:
@model IEnumerable<string> @{ ViewBag.Title = "All speakers"; DisplayModeProvider.Instance.RequireConsistentDisplayMode = false; }
就像剛看到的,演講者視圖可讀性很強,可是連接很小,在移動設備上很難點到。本節將建立移動特定的演講者視圖,讓它看起來像是個時髦的移動程序——顯示大的,容易點擊超連接幷包含一個搜索框,能夠快速找到演講者。
複製 AllSpeakers.cshtml 到 AllSpeakers.Mobile.cshtml。打開 AllSpeakers.Mobile.cshtml 文件並將 <h2>
頭元素移除掉。
在 <ul>
標籤裏, 添加 data-role
屬性並把它的值設爲 listview。
像其餘的 data-*
屬性, data-role="listview"
使得大列表項更容易點擊。完整的標記以下:
@model IEnumerable<string> @{ ViewBag.Title = "All speakers"; } <uldata-role="listview"> @foreach(var speaker in Model) { <li>@Html.ActionLink(speaker, "SessionsBySpeaker", new { speaker })</li> } </ul>
刷新移動瀏覽器。更新後的視圖以下:
雖然移動視圖改善了,但這麼長的演講者列表用起來仍是很費勁。要修復這個缺陷,在 <ul>
標籤裏, 添加 data-filter
屬性並設爲 true
。下面的代碼演示了 ul
標記。
<uldata-role="listview"data-filter="true">
下圖演示了data-filter屬性做用下的頁面頂部的搜索過濾框。
在搜索框裏輸入每個字母, jQuery Mobile 都會過濾顯示列表,以下圖:
正如默認的演講者視圖,標籤視圖也是可讀性挺強的,但在移動設備上連接過小不容易點。本節將修復標籤視圖,就像修復演講者視圖同樣。
將 Views\Home\AllTags.Mobile.cshtml.hide 文件的「hide」後綴去掉,變爲Views\Home\AllTags.Mobile.cshtml。打開重命名後的文件刪掉 <h2>
元素。
添加 data-role
和 data-filter
屬性到 <ul>
標籤中,以下:
<uldata-role="listview"data-filter="true">
下圖演示標籤頁以字母J過濾的結果:
能夠像改善演講者和標籤視圖那樣改善日期視圖,這樣在移動設備上更易用。
複製 Views\Home\AllDates.cshtml 文件到 Views\Home\AllDates.Mobile.cshtml。打開新文件並刪掉<h2>
元素。
增長 data-role="listview"
到 <ul>
標籤中,以下:
<uldata-role="listview">
下圖演示 data-role
屬性下的日期頁面:
用下面的代碼替換 Views\Home\AllDates.Mobile.cshtml文件中的內容:
@model IEnumerable<DateTime> @{ ViewBag.Title = "All dates"; DateTime lastDay = default(DateTime); } <uldata-role="listview"> @foreach(var date in Model) { if (date.Date != lastDay) { lastDay = date.Date; <lidata-role="list-divider">@date.Date.ToString("ddd, MMM dd")</li> } <li>@Html.ActionLink(date.ToString("h:mm tt"), "SessionsByDate", new { date })</li> } </ul>
這段代碼將全部會議按日期分組。它爲每個新的日期建立一個分隔符,並在每個分隔符下列出當天的全部會議。下面是代碼運行後的樣子:
本節將建立一個瀏覽器特定的會議視圖。這裏所作的更改將比以前作的更具擴展性。
在移動瀏覽器中,點擊Speaker按鈕,而後在搜索框中輸入 Sc
。
點擊 Scott Hanselman 連接。
正如所見,顯示的內容在移動瀏覽器中很難看。日期列很難看,標籤列跑出視圖外邊了。要修復此缺陷,複製 Views\Home\SessionsTable.cshtml 到 Views\Home\SessionsTable.Mobile.cshtml,而後用下面的代碼替換文件中的內容:
@using MvcMobile.Models @model IEnumerable<Session><uldata-role="listview"> @foreach(var session in Model) { <li> <ahref="@Url.Action("SessionByCode", new { session.Code })"> <h3>@session.Title</h3> <p><strong>@string.Join(", ", session.Speakers)</strong></p> <p>@session.DateText</p> </a> </li> } </ul>
這段代碼去掉了會議室和標籤列,還垂直顯示格式化後的標題,演講者和日期,使得全部信息在移動瀏覽器中都有很強的可讀性。下圖演示代碼改後的樣子:
最後,建立一個移動特定的SessionByCode視圖。在移動瀏覽器裏,點擊Speaker按鈕,而後再搜索框輸入 Sc
。
點擊 Scott Hanselman 連接, Scott Hanselman的會議就顯示出來了。
選擇 An Overview of the MS Web Stack of Love 連接。
桌面視圖看起來也還好,但還能夠改善。
複製 Views\Home\SessionByCode.cshtml 到 Views\Home\SessionByCode.cshtml 並用下面的代碼替換 Views\Home\SessionByCode.Mobile.cshtml 文件中的內容:
@model MvcMobile.Models.Session @{ ViewBag.Title = "Session details"; } <h2>@Model.Title</h2><p> <strong>@Model.DateText</strong> in <strong>@Model.Room</strong></p><uldata-role="listview"data-inset="true"> <lidata-role="list-divider">Speakers</li> @foreach (var speaker in Model.Speakers) { <li>@Html.ActionLink(speaker, "SessionsBySpeaker", new { speaker })</li> } </ul><p>@Model.Description</p><h4>Code: @Model.Code</h4><uldata-role="listview"data-inset="true"> <lidata-role="list-divider">Tags</li> @foreach (var tag in Model.Tags) { <li>@Html.ActionLink(tag, "SessionsByTag", new { tag })</li> } </ul>
代碼裏用 data-role
屬性來改善視圖的佈局。
刷新移動瀏覽器。下圖演示代碼修改後的結果:
本文介紹了ASP.NET MVC 4的移動特性。包括:
RequireConsistentDisplayMode
屬性控制佈局。