本文地址:http://www.cnblogs.com/egger/p/3400076.html 歡迎轉載 ,請保留此鏈接๑•́ ₃•̀๑!
今天學習MVC4時,看到一個不錯的特性"view override" 。這是個什么功能呢?請看下面的示例。
示例
1.首先創建一個MVC4 Web應用程序,直接默認即可。選擇Internet 模版,視圖引擎 Razor,單元測試項目選不選沒關系反正用不到!
2.項目創建完成后,我們就可以直接運行了!這是MVC默認的主頁 ,路徑“~/home/index”:
我們將Home視圖文件夾下的Index.cshtml 頁面在項目復制下,改下名稱 “Index.Mobile.cshtml”,此時兩個頁面代碼是一致的,我們更改“Index.Mobile.cshtml”頁面中ViewBag的Title屬性 ,改為“Mobile Page”:
我們修改的Title屬性將在下圖中紅框中的位置顯示! Index.cshtml中是Home Page,若運行“Index.Mobile.cshtml”,我們將在紅框出看到的應該是Mobile Page!
3.現在將我們創建的MVC網站發布到IIS中,注意網站應用程序池 .NET Framework 請選擇 4.0,同時將電腦的統自帶的和殺軟的防火牆功能關閉:
4. 將手機連接wifi,打開瀏覽器輸入本地地址+端口號(80就不用了),運行結果如下,出現的是“Mobile Page”。說明此時加載的是 Index.Mobile.cshtml 這個頁面。
5.初次讓人無法理解,我們在Index.Mobile.cshtml 頁面打下斷點,當使用手機進行訪問時,看是否命中,如果命中,那就是Index.Mobile.cshtml沒的跑了:
使用VS附加到進程進行調試(如果找不到玩w3wp.exe,請將“顯示所有用戶的進程”勾選上):
6.手機重新輸入網址或刷新頁面,此時VS斷點已命中說明我們訪問的是Index.Mobile.cshtml !
進一步了解 view override
讀到到這里大家也許會有很多疑惑,為什么創建個Index.Mobile.cshtml 頁面使用手機就能訪問,使用web就不能訪問;那我新建個Index.Phone.cshtml怎么就都訪問不到呢?
我比較好奇系統是怎么分辨出我訪問的設備呢?因為暴漏的代碼中沒有看到相關的功能代碼!
以上的情景在任何設備商都是通過瀏覽器訪問的頁面!不知大家在web開發過程中有沒有遇到需要檢測瀏覽器類型和版本情況,如果做過想必對“Javascript客戶端檢測”和“用戶代理字符串 User-Agent (UA) ”的知識點不陌生,知道我們瀏覽器在進行HTTP請求時會加上 瀏覽器 引擎 版本號等信息,我們可以通過一些明顯的字符進行區分!那么我們剛才看到的效果是否用到的UA的檢測,但是沒有看到相關的代碼呢?
用戶代理字符串簡史: http://www.cnblogs.com/egger/archive/2013/04/20/3032070.html
[Javascript]客戶端檢測: http://www.cnblogs.com/egger/archive/2013/04/26/3045285.html
上面的疑惑我們接下來慢慢解釋,上面演示的功能是MVC4的一個特性: view override 或者 Display Mode。
Dispaly Mode特性相關的類是 DisplayModeProvider [MSDN傳送門]
我們看到DisplayModeProvider 有兩個常量字段 “Mobile” 、 “”。Mobile 應該不陌生把!這個不是我們上面創建的Index.Mobile.cshtml中間的字符嗎。上面我們創建Index.Phone.cshtml就沒有Index.Mobile.cshtml的效果說明c和這兩個常量字段有關!
Display Mode有2個,一個是Mobile、一個是“”。系統根據瀏覽器的類型決定使用訪問哪個View.我們也可以在Application_Start中有加入其他的Display Mode,但是對應的View並沒有對應的view,就會選擇默認View!以Index視圖l為例,訪問視圖的Index.DisplayModeId.cshtml, 若DisplayModeId為“”,就訪問Index.cshtml;如果DisplayModeId為“Mobile”,那就訪問Index.Mobile.cshtml頁面!
也許大家有些頭緒了,原來這么一回事。但是我們上面的疑惑關於如何區分瀏覽器DisplayModeId的機制沒有說!別急我們繼續看上文中說道我們可以在Application_Start中有加入其他的Display Mode,我們先學習下如何操作,請看代碼:
protected void Application_Start() { DisplayModeProvider.Instance.Modes .Insert(0, new DefaultDisplayMode("Android") { ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf ("Android", StringComparison.OrdinalIgnoreCase) >= 0) }); DisplayModeProvider.Instance.Modes .Insert(1, new DefaultDisplayMode("FF") { ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf ("Firefox", StringComparison.OrdinalIgnoreCase) >= 0) }); DisplayModeProvider.Instance.Modes .Insert(2, new DefaultDisplayMode("Chrome") { ContextCondition = (context => context.GetOverriddenUserAgent().IndexOf ("Chrome", StringComparison.OrdinalIgnoreCase) >= 0) }); AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); AuthConfig.RegisterAuth(); }
我在添加了3個 DisplayMode,分別區分android手機瀏覽器、Chrome瀏覽器、Firefox瀏覽器。我們使用 context.GetOverriddenUserAgent() 來獲取UserAgent信息,從而對瀏覽器進行檢測,這證實了我們上面的想法方向對了!
獲取的UA信息:
Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25
初始DisplayMode,只有兩個:
DisplayMode添加完成:
創建頁面后,看看效果如何:
下面是運行截圖:
FF IE 使用默認的視圖
Chrome Android
總結
本文到此就結束了!雖說這特性雖說為了解決移動設備頁面展示問題!但是我們可以靈活運用,怎么用還憑更人發揮!
倉促之間,難免有誤,清指出,謝謝!
相關文章閱讀
http://www.dotblogs.com.tw/rainmaker/archive/2012/06/21/72946.aspx
http://techbrij.com/display-mode-mobile-tablet-tv-aspnet-mvc
http://ericsowell.com/blog/2011/9/27/doing-crazy-things-with-asp-net-mvc-4s-display-modes
http://weblogs.asp.net/gunnarpeipman/archive/2011/09/18/asp-net-mvc-4-display-modes.aspx