Dziś na temat korzystania z jQuery i ciasteczek. Jako scenariusz przyjmijmy proste zliczenie kliknięć, gdzie licznik przechowujemy jako wartość ciastka.
W tym celu tworzymy aplikację ASP.NET MVC wraz z testowym kontrolerem i dwoma widokami – Indeks, który jest widokiem bazowym i Modify, który zwraca kawałek html’a z zawartością ciastka.
Kotroler inicjujemy w następujący sposób:
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Web;
5 using System.Web.Mvc;
6
7 namespace CookieAndJQuery.Controllers
8 {
9 [HandleError]
10 public class TestsController : Controller
11 {
12 private static string CookieName = “TestCookie”;
13
14 public ActionResult Index()
15 {
16 return View();
17 }
18
19 public ActionResult Modify()
20 {
21 HttpCookie cookie = Request.Cookies[CookieName];
22 if (cookie == null)
23 {
24 cookie = new HttpCookie(CookieName, “0”);
25 cookie.Expires = DateTime.MaxValue;
26 }
27
28 int v = int.Parse(cookie.Value);
29 cookie.Value = (++v).ToString();
30 Response.Cookies.Add(cookie);
31 ViewData[“itemValue”]= cookie.Value;
32 return View();
33 }
34 }
35 }
Indeks ma za zadanie po kliknięciu przycisku wywołać akcję Modify w kontrolerze TestsController a następnie wstrzyknąć jej wynik do diva o id=”resultContainer”
2 <html>
3 <head runat=“server”>
4 <title>Index</title>
5 <script src=“Scripts/jquery-1.4.1.min.js” type=“text/javascript”></script>
6 </head>
7 <body>
8 <div>
9 <input type=“button” id=“btnTestCookies” value=“ClickMe” />
10 <div id=“resultContainer”></div>
11 </div>
12 <script type=“text/javascript”>
13 $(“#btnTestCookies”).click(function () {
14 $.ajax(
15 {
16 url: “/Tests/Modify”,
17 success: function (data) {
18 $(“#resultContainer”).html(data);
19 },
20 cache: false,
21 dataType: “html”
22 }
23 );
24 });
25 </script>
26 </body>
27 </html>
Dla pełnego obrazu poniżej widnieje zawartość widoku Modify:
2 <div>
3 <%= ViewData[“itemValue”] %>
4 </div>
Skoro mamy już bazę do doświadczeń pora przejść do sedna problemu, a mianowiscie do obsługi ciastek. Jak zapewne zauważyliście kontroler w linii 25 ustawia czas wygaśnięcia ciastka na DateTime.MaxValue, czyli ciastko nigdy nie wygaśnie. Na pierwszy rzut oka nie widać problemu: wywołujemy akcję, akcja zmienia wartość ciastka, ciastko wraca do przeglądarki, klikamy ponownie, wartość wzrasta – super! Jednakże spójżmy jak faktycznie wygląda ciastko, które otrzymujemy:
Pierwsze wywołanie strony – tworzymy ciastko
Kolejne wywołanie strony – niestety jak widać poniżej czas wygaśnięcia ciastka przypadnie na koniec sesji:
Przez to po zamknięciu i ponownym uruchomieniu przeglądarki ciastko zostanie usuniete a tym samym licznik zostanie zresetowany…
Przyjrzyjmy się jak wygląda request i response. Korzystając z Fiddlera można podejrzeć treść nagłówka Cookies, w którym widać wszystko jak na dłoni:
Odpowiedź po pierwszym wywołaniu (ustawiamy ciastko)
Request przy kojelnych kliknięciach przycisku – jak widać brak przy żądaniu informacji o ekspiracji ciastka, co skuktuje opisanym zachowaniem.
Jak to ominąć? W przypadku, który miałem jako zadanie postanowiłem przy każdym takim wywołaniu ustawiać czas życia ciastka na DateTime.MaxValue, dzięki czemu po ponownym uruchomieniu przeglądarki ciastko nadal tam jest…
2 {
3 HttpCookie cookie = Request.Cookies[CookieName];
4 if (cookie == null)
5 {
6 cookie = new HttpCookie(CookieName, “0”);
7 cookie.Expires = DateTime.MaxValue;
8 }
9
10 cookie.Expires = DateTime.MaxValue;
11 int v = int.Parse(cookie.Value);
12 cookie.Value = (++v).ToString();
13 Response.Cookies.Add(cookie);
14 ViewData[“itemValue”] = cookie.Value;
15 return View();
16 }
W wyniku tej modyfikacji informacja o ciastkach znajdująca się w odpowiedzi wygląda następująco
dzięki czemu przy kolejnym uruchomieniu przeglądarki ciastko nadal tam będzie gotowe do użycia