[MVC]JQM + ASP.NET MVC4 手機程式開發經驗分享
去年底使用Client使用JQM,服務端使用 ASP.NET MVC4來開發手機程式,以下,筆者將開發中所遇到的問題記錄下來,跟大家一起分享。
架構說明
在開發之初,畫面就先請美術設計先搭配 JQM 開發雛型,如下,
因為UI已經設計好了,所以開發人員只需要調整JS去處理存取資料及加入服務端程式。服務端程式則使用ASP.NET MVC4,並搭配Form驗証來處理。
如果Client端程式要放在外網,而服務端程式要放在內網的話,可利用IIS 7的HTTP重新導向到內網的服務端程式虛擬目錄。
問題分享
1.Form驗證, 導到(302)登入頁面問題
因為使用Form驗證,所以未驗証過的Request,會導到(302)登入頁面。但是如果是Ajax來的Request,需要給它401的狀態碼,讓Client端程式知道沒有驗登入過,所以要切到登入畫面。
protected void Application_EndRequest() { var context = new HttpContextWrapper(Context); // 如果是302 & ajax 就回給401 (未經授權) if (Context.Response.StatusCode == 302 && context.Request.IsAjaxRequest()) { Context.Response.Clear(); Context.Response.StatusCode = 401; } }
透過 $(document).ajaxError 來判斷,如果狀態碼是401,就導到登入頁。
$(document).ajaxError(function (e, xhr, settings, exception) { if (xhr.status == "401") { // 401 未授權 要回到登入頁 $.mobile.changePage(‘./../natural/index.htm'); } });
註:
原本的登入程式是先透過jQuery Ajax Call ASP.NET MVC4 Controller登入成功後,再透過Ajax去取得這個登入者的使用語系。
但是這種做法,如果iPhone將首頁存到加入主畫面螢幕,然後開啟來登入的話,筆者發現,如果沒有切頁面的話,Form驗證的cookie會無法寫進去,
而造成雖然Ajax Call Controller已經登入成功了,後面再透過Ajax去取得這個登入者的使用語系,還是會回傳401。
所以後來就改成,如果登入成功,就一併傳回登入者的語系,然後再由Client端程式切換到登入者對應的語系Portal畫面。
2.Client端頁面refresh的問題
原本設計只在第一頁加入JS, CSS,其他頁並沒有加入,所以如果使用者在某一頁按下重新整理的話,畫面就會亂掉,如下,
所以就要在各頁中都要引用必要的JS及CSS,以避免重新整理問題。
<title>批示</title> <meta charset="UTF-8"> <script type="text/javascript" src="../jquery.mobile/jquery-1.8.2.min.js"></script> <link rel="stylesheet" href="../jquery.mobile/jquery.mobile-1.2.0.min.css" /> <script type="text/javascript" src="../jquery.mobile/jquery.mobile-1.2.0.min.js"></script> <link href="../include/custom.css?_v=1.0.0" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="../js/utility.js?_v=1.0.0"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" /> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="yes"> </head>
3.JQM切換頁面時,要執行的JS需要寫在data-role="content"的區塊中,才會被執行到,如下,
<div data-role="page" class="type-interior" id="instruction"> <div data-role="header" data-theme="b"> <h1>批示</h1> <a href="portal.htm" data-icon="grid" data-iconpos="notext" data-direction="reverse"></a> </div> <div data-role="content"> <script type="text/javascript" src="../js/instruction.js"></script> </div> </div> </body>
4.註冊事件,以on取代live
原本美術設計使用live來註冊事件,但發現來回切頁後,會重覆被執行,所以要改用on來取代live,如下,
$('#instruction').live('pageinit', function () {
}
=>
$('#instruction').on('pageinit', function () {
}
5.如何讓頁面永遠都要更新?
切換頁面時,JQM會幫您Cache上一個Page,讓您回一頁時,可以將Cache的那一頁呈現出來。
但是如果我們是批示資料後,回上一頁需要讓該頁面重新整理,才會讓待批示筆數是正確的。
所以筆者的作法是參考「How does one disable Caching in jQuery Mobile UI」作法,
當頁面有設定 data-cache="never" 時,就將Page從Cache中移除,如下,
Html:
<div data-role="page" id="instruction" data-cache="never">
Javascript:
var page = jQuery(event.target); if (page.attr('data-cache') == 'never') { page.remove(); }; });
6.判斷是不是由手機連進來
在「Detect Mobile Browsers」網站中,可download程式來判斷連到系統的是否為手機。
我使用的是jQuery版本的,使用上蠻方便的,只要判斷jQuery.browser.mobile的值是否為true。
var isMobile = jQuery.browser.mobile; if (isMobile) { //切到手機操作URL window.location.href = '手機操作URL'; } else { //切到PC操作的URL window.location.href = 'PC操作的URL'; } });
7.讓iPhone使用者瀏覽網頁時,顯示「加入主畫面螢幕」
在「ADD TO HOME SCREEN」網站中,可download程式,加入頁面之中,讓iPhone使用者瀏覽網頁時,顯示「加入主畫面螢幕」。
8.ASP.NET MVC 4的部署
8.1.在將ASP.NET MVC 4服務端的程式部署到正式機,如果出現 404 的錯誤,可以在web.config的system.webServer中設定modules,如下,
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<validation validateIntegratedModeConfiguration="false" />
<handlers>
...... 省略
</handlers>
<httpRedirect enabled="false" destination="/s2" childOnly="true" httpResponseStatus="Found" />
</system.webServer>
或是在modules中加入 UrlRoutingModule-4.0 module(可參考:Don't use runAllManagedModulesForAllRequests="true" when getting your MVC routing to work),如下,
<system.webServer>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
<!-- any other modules you want to run in MVC e.g. FormsAuthentication, Roles etc. -->
</modules>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
...... 省略
</handlers>
<httpRedirect enabled="false" destination="/s2" childOnly="true" httpResponseStatus="Found" />
</system.webServer>
8.2.如果裝在Windows 2003 IIS6上的話,可參考:ASP.NET MVC 2.0 網站部署到 IIS 6.0 及常見問題排解
使用JQM來開發手機的UI程式實在蠻方便的,我們只要專注在Service部份。
以上是筆者在開發手機程式遇到的相關問題,如果大家有任何想法,麻煩請讓我知道,謝謝大家。
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^