ASP.NET MVC - 在Windows Azure使用TempData要小心!
其實這篇是延續之前寫的"Windows Azure - 使用Windows Azure Storage解決Sessios問題"這個主題,前一篇提到Session在Windows Azure可能會遇到的問題 ( 如果口袋很深的話=v= ),而如果對於ASP.NET MVC比較熟的人,可能就會發現一件事情;沒錯,Session會遇到的問題,在ASP.NET MVC的TempData也會碰到,那是因為TempData是利用Session來進行實作 ( 但詳細的情況小弟我並沒有真的去翻原始碼認證,所以有錯也請告知 ),所以Session抓不到的問題,在ASP.NET MVC的TempData當然也會發生。
同樣的,沒圖沒真相,我們還是稍微實驗一下吧。
開始實驗!
首先,整個專案的檔案大致是這樣,既然是要測試Windows Azure,所以當然要有Windows Azure的專案,然後也別忘了,要將Web Role設定兩個以上,如果只設一個,當然不會發生任何問題了;接下來,我們只利用一個HomeController就可以了;因為要切換頁面,所以我們要ˇ兩個View,一個就是Index,另外一個就是Index2。
反正是本機模擬,執行個體開四個也沒差了,但千萬不要發布上去喔!
HomeControl的程式碼
HomeControl的程式碼很簡單,我們在第一個View (Index),設定了Session、ViewData、ViewBag、TempData來做測試,至於為什麼還要設定ViewData和ViewBag,那是因為小弟之前太蠢了,想說ViewData和ViewBag會不會也和TempData一樣有問題,當初還跑去問David老師,只看到David老師一臉疑惑的看著我XDD;後來回到家裡仔細想想,其實ViewData和ViewBag當然不會有這個問題,理由很簡單,從Control到View這段,其實還在同一台機器上,所以自然不會有這種問題啊!! ( David老師對不起,問了蠢問題QQ ),所以這邊的ViewData和ViewBag看看就好..,其次,我們使用RoleEnvironment.CurrentRoleInstance.Id來取得目前Windows Azure的機器id,用來判斷是否不同台。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Microsoft.WindowsAzure.ServiceRuntime; namespace MvcWebRole1.Controllers { public class HomeController : Controller { // // GET: /Home/ public ActionResult Index() { ViewBag.id = RoleEnvironment.CurrentRoleInstance.Id; Session["Test"] = "Have Value"; ViewData["Test"] = "Have Value"; ViewBag.Test = "Have Value"; TempData["Test"] = "Have Value"; return View(); } public ActionResult Index2() { ViewBag.id = RoleEnvironment.CurrentRoleInstance.Id; return View(); } } }
這樣子Controller就寫好了,接下來我們來看看View。
Index的程式碼
Index裡面很簡單,就是把剛剛那個很糗的ViewData和ViewBag秀出來,基本上,是沒甚麼意義可言啦…,但是ViewBag.id就是有意義的,我們把剛剛抓到的Windows Azure機器id給Show出來,另外,我們最後面加上一個連結,準備連到另外一個View。
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index</title> </head> <body> <h1>@ViewBag.id</h1> <div> Session: @if(Session["Test"] == null) { @:Session is null <br /> }else { @Session["Test"]; <br /> } ViewData: @if (ViewData["Test"] == null) { @:ViewData is null <br /> } else { @ViewData["Test"]; <br /> } ViewBag @if (ViewBag.Test == null) { @:ViewBag is null <br /> } else { @ViewBag.Test;<br /> } @Html.ActionLink("Next", "Index2", "Home"); </div> </body> </html>
到這邊,第一個View就結束了,接下來,我們來看看Index2。
Index2的程式碼
接下來是Index2,我們把剛剛設定好的Session和TempData,Show出在Index2頁面,當然,這邊也要使用ViewBag.id來把Windows Azure上的機器id給Show出來。
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Index2</title> </head> <body> <h1>@ViewBag.id</h1> <div> Session: @if(Session["Test"] == null) { @:Session is null <br /> }else { @Session["Test"]; <br /> Session.Clear(); } TempData: @if (TempData["Test"] == null) { @:TempData is null <br /> } else { @TempData["Test"]; <br /> } </div> </body> </html>
這樣又完成了範例,接下來我們就執行看看。
Run
我們可以發現,目前是在編號1的Windows Azure之下,接下來,我們按下Next,看看下一頁會怎樣。
到了第二頁,我們可以發現目前的id是0,也就是說和第一台是不同台,而這邊我們也可以發現Session是空的,而比較重要的是TempData也為空。
到這邊,實驗就算結束了。
後記
當然,這篇的用意是想提醒大家,使用ASP.NET MVC丟到Windows Azure的時候,使用TempData需要特別的注意,至於解法,可以參考上一篇喔。