ASP.NET MVC Cookie 实现

19

我试图在我的应用程序中实现一个基本的Cookie帮助程序。 主要是在每次基础控制器中检查cookie是否被设置。 如果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;
    }
}

如果会话为null,我会尝试从cookie中获取,或者如果会话初始化,则设置cookie,但我从未在浏览器中看到我的cookie。有什么问题吗?

我始终启动会话,但userId = 0。 要从cookie获取并设置会话:

if (userId == 0)
{
    MyCookie myCookie = new MyCookie(_app);
    User user = cookieHelper.GetCookie();
    if (user != null)
        SessionHelper.SetSession(user);
}

5
你的代码看起来不错。你能否发一下调用它的代码? - Kirk Woll
4
那个新的代码片段(if (userId == 0))在哪里?你把那段代码放在哪个控制器方法里了?另外,为什么下面要用CookieHelper,而上面却用了MyCookie?还有一个GetCookie方法返回一个HttpCookie,但是调用另一个GetCookie方法却返回一个User,这让我感到很困惑。 - Kirk Woll
2
我总是在基础控制器中初始化会话。如果没有用户登录,我会将会话设置为用户ID 0。实际上,它们都是MyCookie。但因为我在等待stackoverflow的答案时尝试了一些东西,所以我同时编辑了问题和代码。 - gandil
3个回答

19
你不能在同一个请求中设置和获取cookie。获取cookie是从浏览器中获取它,但浏览器尚未获取它 - 设置cookie使其准备在请求完成时作为标头的一部分发送回去。
你需要设置cookie,并让浏览器重定向到其他地方(例如从/login到/account),然后在新请求中读取它将正确显示cookie。
编辑: 如果那个猜测是错误的,我还会质疑你实际上在哪里调用.SetCookie(),因为在你提供的代码中,你根本没有调用它来创建cookie。
为了调试这些问题,我发现最好把你认为应该工作的代码片段测试一下。例如,在新页面的page_load中,我输入了以下内容:
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);

而且cookie已经正确显示,没有任何问题。因此,知道这段代码确实有效,我们可以假设错误是因为函数未被调用或者你当前正在尝试在同一请求中设置和读取cookie并失败了(就像我最初所述的那样)。

无论如何,祝你好运!


1
同意!只有当浏览器发送回请求后,您才能读取cookie。我曾经遇到过这样的问题...但我在一分钟内解决了它 :)..我来自1999年的PHP学校 :) - effkay

14

我的工作实现(基础版)

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);
 }
 }
如果会话/cookie为空(实际上是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);
        }
    }
}

1
尝试这个。
HttpCookie cookie = new HttpCookie("Remember_Me");
cookie["userID"] = Userid.ToString();
cookie.Expires = DateTime.Now.AddMonths(3);
Response.Cookies.Add(cookie);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接