[MVC]JQM + ASP.NET MVC4 手機程式開發經驗分享

[MVC]JQM + ASP.NET MVC4 手機程式開發經驗分享

去年底使用Client使用JQM,服務端使用 ASP.NET MVC4來開發手機程式,以下,筆者將開發中所遇到的問題記錄下來,跟大家一起分享。

 

架構說明

在開發之初,畫面就先請美術設計先搭配 JQM 開發雛型,如下,

image

 

因為UI已經設計好了,所以開發人員只需要調整JS去處理存取資料及加入服務端程式。服務端程式則使用ASP.NET MVC4,並搭配Form驗証來處理。

image

 

如果Client端程式要放在外網,而服務端程式要放在內網的話,可利用IIS 7的HTTP重新導向到內網的服務端程式虛擬目錄。

image

 

問題分享

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畫面。

image

 

2.Client端頁面refresh的問題

原本設計只在第一頁加入JS, CSS,其他頁並沒有加入,所以如果使用者在某一頁按下重新整理的話,畫面就會亂掉,如下,

image

 

所以就要在各頁中都要引用必要的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,如下,

image

 

$('#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使用者瀏覽網頁時,顯示「加入主畫面螢幕」。

image

 

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:從零開始的軟體開發生活

請大家繼續支持 ^_^