2011-07-22 87 views
6

我正在使用ASP.NET MVC 3 w/Razor並開發2個不同視圖的同一站點,完整版本和移動版本的新項目。使用相同控制器的最佳實踐/方法是什麼?但是基於用戶代理顯示不同的視圖?我應該在控制器中處理這個問題嗎?看起來,如果每個控制器中的語句檢查用戶代理,然後根據其設備返回不同的視圖,這似乎很麻煩,多餘,容易出錯。ASP.NET MVC使用相同的控制器分離移動視圖

+2

我想這是值得一提,這是*計劃*對於MVC 4 http://aspnet.codeplex.com/wikipage?title=ASP.NET%20MVC%204%20RoadMap –

+0

請將asnwer標記爲正確的。 –

回答

7

這現在可以使用來實現內置的(從版本4起)被稱爲「DisplayModes

默認情況下,ASP.NET MVC附帶兩種顯示模式內置ASP.NET MVC的功能。這裏有默認的顯示模式,它像往常一樣渲染你的「標準」視圖,還有一個通用的「移動」顯示模式。

這可以通過檢測客戶端設備是否爲移動瀏覽器(其本身是通過嗅探客戶端設備的User-Agent string從而不是100%可靠)來工作的。如果設備被確定爲移動設備,則發送給客戶端的實際MVC視圖將被覆蓋,並替代地呈現併發送替代視圖。在所包括的移動顯示模式的情況下,它的配置爲查找與.mobile.cshtml後綴一個視圖而不是.cshtml(如在下面的屏幕截圖示出)

Image of solution explorer showing mobile view file

這樣就可以設計出完全不同的觀點這將被髮送到移動設備而非移動設備,而不需要對您的控制器邏輯進行任何更改,因此您不需要在其中包含任何條件邏輯。

如果您需要更精確地控制發送到客戶端設備的精確視圖,則整個顯示模式功能是可配置和可擴展的。您可以定義您自己的顯示模式(通常在應用程序啓動時執行),這些模式可以是特定的瀏覽器,給定設備或您希望的任意定義。所有都基於來自客戶端設備的用戶代理字符串。

考慮下面的代碼片斷下面示出在應用程序啓動方法加入3種附加的定製顯示模式爲Windows電話,iPhone和Android:

protected void Application_Start() 
{ 
    DisplayModeProvider.Instance.Modes.Insert(0, new DefaultDisplayMode("WP") 
    { 
     ContextCondition = (context => context.GetOverriddenUserAgent(). 
      IndexOf("Windows Phone OS",StringComparison.OrdinalIgnoreCase) >= 0) 
    }); 

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

    DisplayModeProvider.Instance.Modes.Insert(2, new DefaultDisplayMode("Android") 
    { 
     ContextCondition = (context => context.GetOverriddenUserAgent(). 
      IndexOf("Android", StringComparison.OrdinalIgnoreCase) >= 0) 
    }); 
} 

每個顯示模式被賦予一個ID和一個串到匹配用戶代理字符串以確定是否使用此顯示模式。如果是,則DisplayModeProvider將查找具有相同字符串後綴的View。 (例如,對於上面的iPhone顯示模式,我們希望在用戶代理字符串中的任何位置找到字符串「iPhone」,如果存在,我們使用此顯示模式,以iphone.cshtml後綴呈現視圖,而不是.cshtml後綴

你可以閱讀更多有關此功能在這裏:在部分 http://www.asp.net/mvc/overview/older-versions/aspnet-mvc-4-mobile-features 專門爲首的「重寫次數,佈局和局部視圖」和「瀏覽器的具體意見」

+0

謝謝grea回答!基於你的回答,我想在後面的代碼中構建不同圖像的路徑,而不是在「視圖」中。某種程度上可以在控制器中執行嗎? –

相關問題