Shaokan
Shaokan

Reputation: 7684

How to store an object in a cookie?

While this is possible in C#: (User is a L2S class in this instance)

User user = // function to get user
Session["User"] = user;

why this is not possible?

User user = // function to get user
HttpCookie cookie = new HttpCookie();
cookie.Value = user; 

and how can it be done? I don't want to store the id of the user within the cookie and then do some validation.

Btw, if possible, is it secure to store an object within a cookie rather than only the ID ?

Upvotes: 15

Views: 56392

Answers (10)

Igal C
Igal C

Reputation: 45

Cookie store only strings. What you can do:

 var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
 var json = serializer.Serialize(user);
controller.Response.SetCookie(
        new HttpCookie({string_name}, json)
        {
            Expires = false // use this when you want to delete
                    ? DateTime.Now.AddMonths(-1)
                    : DateTime.Now.Add({expiration})
        });

This should insert the entire object to cookie.

In order to read from the cookie back to an object:

    public static {Object_Name} GetUser(this Controller controller)
    {

        var httpRequest = controller.Request;

        if (httpRequest.Cookies[{cookie_name}] == null)
        {
            return null;
        }
        else
        {
            var json = httpRequest.Cookies[{cookie_name}].Value;
            var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            var result = serializer.Deserialize<{object_name}>(json);
            return result;
        }

    }

Upvotes: 0

Opochitsky Dimitry
Opochitsky Dimitry

Reputation: 64

to store an object in a cookie we have to convert it into stringified presentation (compressed or not) which is limited to 4kb. this example demonstrates how to keep a little "Buy" object in a cookies (save/prolong/reset/clear). instead of separate code lines i've used a Json to fill this object with some data.

using System;
using System.Collections.Generic;
using System.Web;
using Newtonsoft.Json;
public class Customer
{
    public int id;
    public string name;
}
public class Order
{
    public int id;
    public decimal total;
    public Customer customer;
}
public class OrderItem
{
    public int id;
    public string name;
    public decimal price;
}
public class Buy
{
    public Order order;
    public List<OrderItem> cart;
}
static readonly string cookieName = @"buy";
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    if (!IsPostBack)
        Restore_Click(null, null);
}
protected void Save_Click(object sender, EventArgs e)
{
    string buy = JsonConvert.SerializeObject(new
    {
        order = new
        {
            id = 1,
            total = 20.10,
            customer = new
            {
                id = 1,
                name = "Stackoverflow"
            }
        },
        cart = new[] {
            new {
                id = 1 , 
                name = "Stack",
                price = 10.05 
            },
            new {
                id = 2 , 
                name = "Overflow",
                price = 10.05 
            }
        }
    });
    HttpContext.Current.Response.Cookies.Add(
        new HttpCookie(cookieName, buy) {
            Expires = DateTime.Now.AddDays(7)
        }
    );
    StatusLabel.Text = "Saved";
}
protected void Prolong_Click(object sender, EventArgs e)
{
    HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieName];
    if (cookie != null)
    {
        cookie.Expires = DateTime.Now.AddDays(7);
        HttpContext.Current.Response.Cookies.Add(cookie);
        StatusLabel.Text = "Prolonged";
    }
    else StatusLabel.Text = "Not prolonged - expired";
}
protected void Restore_Click(object sender, EventArgs e)
{
    Buy buy = null;
    HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieName];
    if (cookie != null)
    {
        buy = JsonConvert.DeserializeObject<Buy>(cookie.Value);
        StatusLabel.Text = "Restored";
    }
    else StatusLabel.Text = "Not restored - expired";
}
protected void ClearOut_Click(object sender, EventArgs e)
{
    HttpCookie cookie = HttpContext.Current.Request.Cookies[cookieName];
    if (cookie != null)
    {
        cookie.Expires = DateTime.Now.AddMonths(-1);
        HttpContext.Current.Response.Cookies.Add(cookie);
        StatusLabel.Text = "Cleared out";
    }
    else StatusLabel.Text = "Not found - expired";
}

Upvotes: 0

Ahsan Ahmad
Ahsan Ahmad

Reputation: 999

you can try this:

public void AddToCookie(SessionUser sessionUser)
    {
        var httpCookie = HttpContext.Current.Response.Cookies["SessionUser"];
        if (httpCookie != null)
        {
            httpCookie["ID"] = sessionUser.ID.ToString();
            httpCookie["Name"] = sessionUser.Name;
            httpCookie["Email"] = sessionUser.Email;
            httpCookie["Phone"] = sessionUser.Phone;
            httpCookie.Expires = DateTime.Now.AddDays(1);
        }

    }

Upvotes: 0

Ankita Singh
Ankita Singh

Reputation: 629

System.Collections.Specialized.NameValueCollection cookiecoll = new System.Collections.Specialized.NameValueCollection();

            cookiecoll.Add(bizID.ToString(), rate.ToString());


        HttpCookie cookielist = new HttpCookie("MyListOfCookies");
        cookielist.Values.Add(cookiecoll);
        HttpContext.Current.Response.Cookies.Add(cookielist);

Upvotes: 0

Erik Bergstedt
Erik Bergstedt

Reputation: 912

You can use JSON

string myObjectJson = new JavaScriptSerializer().Serialize(myObject);
var cookie = new HttpCookie("myObjectKey", myObjectJson) 
{     
    Expires = DateTime.Now.AddYears(1) 
};
HttpContext.Response.Cookies.Add(cookie);

Upvotes: 13

Sonu
Sonu

Reputation: 458

in cookie you can store a value of type string. you can store your object into session,viewstate or in cache. but still want to store in cookies, just use system.web.script.javascriptserialization class and convert the whole object in json string and then store that on your cookie.

Upvotes: 0

sgtz
sgtz

Reputation: 9019

you could encrypt such a cookie as well. The contents (json/xml/etc) would be a bit safer then. Server-side caching as Marc suggests is probably better.

Tradeoff: increased traffic on the wire (cookies are passed back and forth) Vs larger server-side memory footprint and / or secondardy storage.

btw: don't forget that binary can be encoded to text if you really need that.

http://www.codeproject.com/KB/security/TextCoDec.aspx

Upvotes: 1

Chris Miller
Chris Miller

Reputation: 763

Try something like this?

StringWriter outStream = new StringWriter();
XmlSerializer s = new XmlSerializer(typeof(List<List<string>>));
s.Serialize(outStream, myObj);
cookie.Value = outStream.ToString();

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1062770

A cookie is just string data; the only way to do that would be to serialize it as a string (xml, json, base-64 of arbitrary binary, whatever), however, you shouldn't really trust anything in a cookie if it relates to security information ("who am I?") as a: it is easy for the end-user to change it, and b: you don't want the overhead of anything biggish on every single request.

IMO, caching this as the server is the correct thing; don't put this in a cookie.

Upvotes: 15

p.campbell
p.campbell

Reputation: 100567

The short answer is: Cookies store strings, and not binary objects.

You could serialize your object into strings or JSON if you really wanted to. Suggest keeping the data back/forth as lightweight as you can. Remember: each time we communicate from the browser to the server, you're passing all that data each time.

Upvotes: 4

Related Questions