ASP.NET MVC - ASP.NET MVC 4 Display Modes

19 September 2011 — Written by Sky Chang
#ASP.NET MVC

2012/02/25 配合Beta大幅度更新!! 幾乎全更新了= =

經過上一篇騙完稿費認真介紹完後,為了不要讓大家太失望,所以我們介紹一下,Display Modes!,這就是ASP.NET MVC 4的新技術了,雖然說,我們可以開發Mobile專案,但如果我們今天同一個網址,要讓行動裝置和PC呈現的感覺不一樣呢?而且又不想利用HTML配合CSS動態調整樣板的方式,想針對行動裝置做不同的頁面,但是同網址,該怎麼辦呢?沒錯,這就是Display Modes的目的。

在說Display Modes之前,有一點要先聲明,前面為什麼我會稱為"範例樣本",是因為我覺得這些算是範例的展示,通常我還是習慣開一個空白的慢慢加,並不一定說我要開發手機,就必須要使用手機樣板,我只要把開發手機上所需要的東西於空白專案內準備好就好了( 例如:jQuery Mobile ),我也可以在空白樣板上面實作桌上型的網頁和手機上的網頁,我只要使用Display Modes就可以了,簡單的說,我覺得這"範例樣板"只是方便於展示、快速使用而已,所以我會稱之為"範例樣板"。

ok,回到主題,我們現在要探討的是Display Modes,其實他的概念很簡單,只是去判斷你是否用行動裝置上網,如果是,就顯示行動專用的View,如果不是,就顯示一般的View,所以我現在要將原本的Application範例樣板,加上Mobile的範例樣板。

其實這個Demo還滿無聊的,所以不想看Demo,只想看怎麼實作Display Modes的人,可以直接跳到最後。

首先,我們在桌上型電腦上看到的畫面會是。

image

ok,現在我們開始打造( 複製 ),首先,我們先在目標的專案上,建立一個MobileContent的目錄,準備來存放專門給Mobile用的CSS。

image

然後我們把行動範例樣板上的Content底下的Images整個目錄還有jQuery.mobile開頭的css和Site.css拷貝到這個專案的MobileContent目錄下,然後Scripts目錄下的jQuery.mobile開頭的js也拷貝過來;因為ASP.NET MVC 4的Mobile專案,實際上是使用jQuery Mobile來達成Mobile頁面的效果,而這些檔案也正是jQuery Mobile要用到的檔案,要拷貝的檔案如下圖。

image

接下來,我們把行動板的view拷貝過來,並且重新命名,例如:行動版的首頁名稱叫做index.cshtml,那我們先改名成index.mobile.cshtml並且複製到此專案,其餘的Layout.cshtml也是一樣,改名為Layout.mobile.cshtml後,複製到此專案,然後也把jQuery.mobile和image複製過來,完成後如下圖。( 這裡只針對首頁,其他的頁面因為太懶了,就不動了 )

image

做到這邊,大家應該就有感覺了,沒錯,ASP.NET MVC 4的Display Modes,其實就是利用檔名來辨別要顯示的網頁,所以當手機瀏覽時就會自動執行有mobile的檔案,例如手機執行首頁時,他就不會呼叫index.cshtml而是會呼叫index.mobile.cshtml,同樣道理也適用於Layout,所以Layout.mobile的檔案,就是給行動裝置使用;接下來,我們要修改一下Global.asax這個檔案;我們要把BundleTable.Bundles.RegisterTemplateBundles();這個註解起來,並起換上BundleTable.Bundles.EnableDefaultBundles();。

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    BundleTable.Bundles.EnableDefaultBundles();

    //BundleTable.Bundles.RegisterTemplateBundles();
}

BundleTable.Bundles.RegisterTemplateBundles();也是ASP.NET MVC 4的新功能,它可以將整個CSS或是JS目錄包裝起來,讓傳輸更有效率,而BundleTable.Bundles.RegisterTemplateBundles();代表著使用預設的樣板目錄,但因為我們的Mobile用CSS是放在MobileContent,和原本預設的樣板目錄( Content )不一樣,所以我們要改用BundleTable.Bundles.EnableDefaultBundles();這個方法,這個發法就可以自訂自己想要包裝的目錄,未來會有一篇專門的主題來講這個,這裡暫時先講到這邊。

然後我們改一下_Layout.mobile.cshtml程式碼,讓他能把整個MobileContent這個目錄下的css包起來。( 下面的路徑是寫著MobileContent/css,但不代表是把css目錄下的東西包起來,而是代表著MobileContent底下所有的css檔案。 )

image

完成後編譯執行,並利用手機上網,就可以看到下面這個頁面了!!( 我很想拿Windows Phone Demo,但我只有iPhone… )

IMG_0375

所以,就如前面所說,Display Modes提供了一個讓不同裝置可以瀏覽不同頁面的方式,而且不需要更改到程式碼,ASP.NET MVC會自動辨識,只需要另外增加一個含有mobile的檔名 ( 例如 :  index.mobile.cshtml就是給行動裝置用的 ),而且不只普通的view,連Layout也一樣適用!

最後一個程式碼,如果今天要針對不同的行動裝置產生不同的頁面,該怎麼辦呢?這時候,就必須去修改Global.asax。

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    BundleTable.Bundles.EnableDefaultBundles();

    //BundleTable.Bundles.RegisterTemplateBundles();
    DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("iPhone")
    {
        ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf
            ("iPhone", StringComparison.OrdinalIgnoreCase) >= 0)
    });
}

如上程式碼,就定義了給iPhone裝置用的,所以我們就可以將檔案命名為index.iPhone.cshtml,這樣ASP.NET MVC遇到iPhone就會執行這個view。

最後,這次的ASP.NET MVC 4為了配合未來行動裝置,所以提供了這一解決方案,也善加的利用了ASP.NET MVC的特性,簡單且易懂的方式來拆離原本要處理各種行動裝置的複雜問題,但每次要增加那麼多東西,其實還滿麻煩的,所以如果使用NuGet取得jQuery Mobile,其實剛剛我們做過的動作,NuGet都會自動幫我們執行完畢 ( 說到這,會不會打我啊QQ ),但無論如何,我相信,看過一遍,會更加的明瞭整個增加的東西與架構,所以,請大家不要罵我喔~~

參考資料

Sky & Study4.TW