ASP.NET MVC Cookie Implementation
Asked Answered
S

3

19

I try to implement a basic cookie helper in my application. Mainly I check in base controller everytime whether or not if cookie is set. If cookie

public class MyCookie
{

    public static string CookieName {get;set;}
    public virtual User User { get; set; }
    public virtual Application App { get; set; }


    public MyCookie(Application app)
    {
        CookieName = "MyCookie" + app;
        App = app;
    }

    public void SetCookie(User user)
    {
        HttpCookie myCookie = HttpContext.Current.Request.Cookies[CookieName] ?? new HttpCookie(CookieName);
        myCookie.Values["UserId"] = user.UserId.ToString();
        myCookie.Values["LastVisit"] = DateTime.Now.ToString();
        myCookie.Expires = DateTime.Now.AddDays(365);
        HttpContext.Current.Response.Cookies.Add(myCookie);
    }

    public HttpCookie GetCookie()
    {
        HttpCookie myCookie = HttpContext.Current.Request.Cookies[CookieName];
        if(myCookie != null)
        {
            int userId = Convert.ToInt32(myCookie.Values["UserId"]);
            User user = session.Get<User>(userId);
            return user;
        }
        return null;
    }
}

if session is null I try to get from cookie or if session initialize I set cookie but I never see my cookie in browser. What is wrong?

I always start session but with userId=0 To get cookie and set session from cookie:

if (userId == 0)
{
    MyCookie myCookie = new MyCookie(_app);
    User user = cookieHelper.GetCookie();
    if (user != null)
        SessionHelper.SetSession(user);
}
Seventh answered 23/7, 2011 at 0:10 Comment(3)
Your code looks good to me. Can you post the code where you're calling it?Penman
Where is that new snippet (if (userId == 0)) located? Where did you put that code? What controller method, etc.? Also, why are you using CookieHelper below, and MyCookie above? And why does one GetCookie method return an HttpCookie yet when you invoke the other GetCookie method it return a User. I'm quite confused.Penman
I always initilalize session in base controller. If there is no user logged in I set session with user id 0. Actuallu both of them are MyCookie. But because I edit question meanwhile my code is changed. Because I try something while I wait for an answer from stackoverflow.Seventh
S
14

My Working Implementation (Basic Version)

public class CookieHelper
{

public static string CookieName {get;set;}
public virtual Application App { get; set; }


public MyCookie(Application app)
{
    CookieName = "MyCookie" + app;
}

public static void SetCookie(User user, Community community, int cookieExpireDate = 30)
{
    HttpCookie myCookie= new HttpCookie(CookieName);
    myCookie["UserId"] = user.UserId.ToString();
    myCookie.Expires = DateTime.Now.AddDays(cookieExpireDate);
    HttpContext.Current.Response.Cookies.Add(myCookie);
 }
 }

if session/cookie is null (actually userid=0)

if (userId == 0){
    CookieHelper myCookie = new Cookie(_app);
    if (myCookie  != null)
    {
        userId = Convert.ToInt32(System.Web.HttpContext.Current.Request.Cookies[myCookie.CookieName]["userId"]);
        if(userId>0)
        {
           SessionHelper.SetSession(userId);
        }
    }
}
Seventh answered 29/7, 2011 at 20:15 Comment(0)
B
19

You can't set and get a cookie in the same request. Getting a cookie gets it from the browser and it hasn't gotten it yet - Setting a cookie preps it to be sent back as part of the header when the request has completed.

You need to set the cookie and get the browser to perhaps redirect somewhere else (eg from /login to /account) then on the new request reading it will show the cookie correctly.

EDIT: In case that guess was wrong, i would also question where you are actually calling .SetCookie() as nowhere in the code you have provided are you actually calling it to create the cookie in the first place.

To debug these things i find it good to take bits of the code you assume should work, test them. For example in the page_load of a new page i entered this:

string CookieName = "bob";
long UserId = 4;
HttpCookie myCookie = HttpContext.Current.Request.Cookies[CookieName] ?? new HttpCookie(CookieName);
myCookie.Values["UserId"] = UserId.ToString();
myCookie.Values["LastVisit"] = DateTime.Now.ToString();
myCookie.Expires = DateTime.Now.AddDays(365);
HttpContext.Current.Response.Cookies.Add(myCookie);

And the cookie appeared correctly without a problem. So knowing this code actually does work we can assume the error is the function not being called or the testing/debugging you are currentlying doing is trying to set and read the cookie in the same request and failing (as i originally stated)

Either way good luck!

Bocock answered 25/7, 2011 at 1:20 Comment(1)
Agree! You can only read cookie once Browser has SENT BACK the request. I have been a victim of such problem ... but I figured out in a minute :) .. I come from year 1999's PHP school :)Lithea
S
14

My Working Implementation (Basic Version)

public class CookieHelper
{

public static string CookieName {get;set;}
public virtual Application App { get; set; }


public MyCookie(Application app)
{
    CookieName = "MyCookie" + app;
}

public static void SetCookie(User user, Community community, int cookieExpireDate = 30)
{
    HttpCookie myCookie= new HttpCookie(CookieName);
    myCookie["UserId"] = user.UserId.ToString();
    myCookie.Expires = DateTime.Now.AddDays(cookieExpireDate);
    HttpContext.Current.Response.Cookies.Add(myCookie);
 }
 }

if session/cookie is null (actually userid=0)

if (userId == 0){
    CookieHelper myCookie = new Cookie(_app);
    if (myCookie  != null)
    {
        userId = Convert.ToInt32(System.Web.HttpContext.Current.Request.Cookies[myCookie.CookieName]["userId"]);
        if(userId>0)
        {
           SessionHelper.SetSession(userId);
        }
    }
}
Seventh answered 29/7, 2011 at 20:15 Comment(0)
T
1

Try this

HttpCookie cookie = new HttpCookie("Remember_Me");
cookie["userID"] = Userid.ToString();
cookie.Expires = DateTime.Now.AddMonths(3);
Response.Cookies.Add(cookie);
Taffeta answered 4/7, 2017 at 8:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.