Wednesday, September 16, 2009

CookieProxy

A CookieProxy class to access cookies in a strongly typed way:
using System;
using System.Linq;
using System.Web;

public class CookieProxy
{
    public HttpRequest Request { get; set; }

    public HttpResponse Response { get; set; }

    public CookieProxy()
    {
    }

    public CookieProxy(HttpRequest request, HttpResponse response)
    {
        this.Request = request;
        this.Response = response;
    }

    public string GetCookieKey(string name)
    {
        return string.Format("{0}", name);
    }

    private string GetCookie(string name)
    {
        if (this.Response.Cookies.AllKeys.Contains(this.GetCookieKey(name)))
        {
            return this.Response.Cookies[this.GetCookieKey(name)].Value;
        }
        else
        {
            return this.Request.Cookies[this.GetCookieKey(name)] != null ? this.Request.Cookies[this.GetCookieKey(name)].Value : null;
        }
    }

    private void SetCookie(string name, string value)
    {
        HttpCookie cookie = this.CreateCookie(name, value);
        if (this.Response.Cookies.AllKeys.Contains(this.GetCookieKey(name)))
        {
            this.Response.Cookies.Set(cookie);
        }
        else
        {
            this.Response.Cookies.Add(cookie);
        }

    }

    public HttpCookie CreateCookie(string name, string value)
    {
        HttpCookie cookie = new HttpCookie(GetCookieKey(name), value);
        cookie.Path = this.Request.ApplicationPath;
        cookie.Expires = DateTime.Now.AddYears(10);
        return cookie;
    }

    // Sample cookie.
    public string Culture
    {
        get { return this.GetCookie("Culture"); }
        set { this.SetCookie("Culture", value); }
    }
}
And a property in your application's base page:
private CookieProxy cookies;

public CookieProxy Cookies
{
    get
    {
        if (this.cookies == null)
        {
            this.cookies = new CookieProxy(this.Request, this.Response);
        }
        return this.cookies;
    }
}
How do I use it in a page?
string culture = this.Cookies.Culture;
How do I use it in a MasterPage or a UserControl?
string culture = this.Page.Cookies.Culture;
Oh, and there's a catch when you are using cookies with path - the path is case sensitive. Here's the code to get rid of the problem (place it in your Global.asax file):
void Application_BeginRequest(object sender, EventArgs e)
{
    // If the application path casing is different from ApplicationPath, retrieve the url again with proper casing to avoid cookies problems.
    // http://stackoverflow.com/questions/1121695/cookies-case-sensitive-paths-how-to-rewrite-urls
    string url = HttpContext.Current.Request.Url.PathAndQuery;
    string application = HttpContext.Current.Request.ApplicationPath;
    if (!url.StartsWith(application))
    {
        HttpContext.Current.Response.Redirect(application + url.Substring(application.Length));
    }
}

No comments: