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.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需要特別的注意,至於解法,可以參考上一篇喔。