I’m looking forward to the Profile Store in EPiServer, but in the mean time I want some information to be remembered.
You can, of course, create your own persistent visitor groups, but who knows what will change when the Profile Store arrives.
I just wanted the Visited Pages to be remembered, and perhaps the Visited Categories. These are stored in your session, so until it is clear what will change when the Profile Store arrives, I opted for "hack".
In the base class for my page controllers i added the following:
public virtual void UpdateViewedPagesCookie() { HttpSessionStateBase httpSessionStateBase = null; try { httpSessionStateBase = this.ControllerContext.HttpContext.Session; } catch (NotImplementedException) { } if (httpSessionStateBase == null) { return; } HashSet<PageReference> viewedPages = null; try { viewedPages = httpSessionStateBase["EPi:ViewedPages"] as HashSet<PageReference>; } catch (NotImplementedException) { } if (viewedPages == null) { return; } string content = JsonConvert.SerializeObject(viewedPages); HttpCookie myCookie = this.Request.Cookies["EPi: ViewedPages"]; if (myCookie == null) { try { myCookie = new HttpCookie("EPi: ViewedPages") { Value = content, Expires = DateTime.Now.AddYears(1) }; this.Response.Cookies.Add(myCookie); } catch (ArgumentOutOfRangeException) { } catch (NotImplementedException) { } return; } try { myCookie.Value = content; myCookie.Expires = DateTime.Now.AddYears(1); this.Response.Cookies.Set(myCookie); } catch (ArgumentOutOfRangeException) { } catch (NotImplementedException) { } } public void UpdateVisitedCategoriesCookie() { HttpSessionStateBase httpSessionStateBase = null; try { httpSessionStateBase = this.ControllerContext.HttpContext.Session; } catch (NotImplementedException) { } if (httpSessionStateBase == null) { return; } HashSet<PageReference> viewdcategories = null; try { foreach (string key in httpSessionStateBase.Keys.Cast<string>().Where(key => key.Contains("EPi:VisitedCategories"))) { HttpCookie myCookie = this.Request.Cookies[key]; string content = string.Empty; try { viewdcategories = httpSessionStateBase[key] as HashSet<PageReference>; } catch (NotImplementedException) { } content = viewdcategories != null ? JsonConvert.SerializeObject(viewdcategories) : JsonConvert.SerializeObject(true); if (myCookie == null) { try { myCookie = new HttpCookie(key) { Value = content, Expires = DateTime.Now.AddYears(1) }; this.Response.Cookies.Add(myCookie); } catch (ArgumentOutOfRangeException) { } catch (NotImplementedException) { } } else { try { myCookie.Value = content; myCookie.Expires = DateTime.Now.AddYears(1); this.Response.Cookies.Set(myCookie); } catch (ArgumentOutOfRangeException) { } catch (NotImplementedException) { } } } } catch (NotImplementedException) { } catch (ArgumentNullException) { } catch (InvalidCastException) { } }
All I do is create/update cookies for the session variables that the Visited Pages and Visited Categories use.
In the Session_Start of the global. asax you can set the session again with information from those cookies:
public class EPiServerApplication : EPiServer.Global { protected void Session_Start(object sender, EventArgs e) { this.UpdateViewedPagesSession(); this.UpdateViewedCategoriesSession(); } protected void UpdateViewedPagesSession() { HttpCookie myCookie = null; try { myCookie = this.Request.Cookies["EPi: ViewedPages"]; } catch (HttpException) { } if (myCookie == null) { return; } HashSet<PageReference> viewedPages = JsonConvert.DeserializeObject<HashSet<PageReference>>(myCookie.Value); HttpContext.Current.Session["EPi:ViewedPages"] = viewedPages; } protected void UpdateViewedCategoriesSession() { try { foreach (string key in this.Request.Cookies.Keys.Cast<string>().Where(key => key.Contains("EPi:VisitedCategories"))) { HttpCookie myCookie = null; try { myCookie = this.Request.Cookies[key]; } catch (HttpException) { } if (myCookie == null) { return; } if (myCookie.Value.Equals("true", StringComparison.OrdinalIgnoreCase)) { HttpContext.Current.Session[key] = JsonConvert.DeserializeObject<bool>("true"); } else { HashSet<PageReference> viewedCategories = JsonConvert.DeserializeObject<HashSet<PageReference>>(myCookie.Value); HttpContext.Current.Session[key] = viewedCategories; } } } catch (HttpException) { } catch (ArgumentNullException) { } catch (InvalidCastException) { } catch (ArgumentException) { } }
As I said, until I know more about what will happen with the Profile Store, I opt for this way, although a bit hackish… It can be easily removed and does not introduce new stuff that might need to be completely rewritten and/or migrated when the Profile Store arrives.
You can also find the code in a gist.
Interesting approach, I did something similar with CookieDropBlock – Seems I’m another person who can’t wait for the Profile Store to arrive 🙂
LikeLike
Indeed! Can’t wait. Hope more will be known soon, so we know which way to go
LikeLike
Just dig a quick reas but it seams to solve a problem that I have been thinking about recently.
LikeLike
Cool!
LikeLike