【问题标题】:Disappearing Cookie in MVC4 after creation in HttpModule在 HttpModule 中创建后在 MVC4 中消失的 Cookie
【发布时间】:2012-07-11 15:28:54
【问题描述】:

我创建了一个模块来处理 Microsoft HealthVault 的身份验证。在 BeginRequest 事件处理程序中,我正在检查 authToken,当收到它时,我正在创建一个新的 cookie 来保存用户的信息,以便稍后在控制器中使用。

我丢失了 cookie,但也许我找错地方了。

事件处理程序将 HttpApplication 作为唯一参数,因此我将 cookie 添加到 application.Response.Cookies 集合中。问题归结为:这个 HttpApplication 实例是单例吗?和 System.Web.HttpContext.Current.ApplicationInstance 一样吗?

也许,在生命周期的这一点设置的 cookie 稍后会被清除。那是我做错了吗?

非常感谢任何帮助。

更新

自从我提出这个问题以来,我已经改变了一些事情。我现在在我的 HttpModule 中处理 PreRequestEventHandler。我让 HealthVault 的 WebApplicationUtilities 对象来创建和存储 cookie,尽管从概念上来说并没有真正改变。创建 cookie 或在创建 cookie 后 第一次 读取它时,我没有遇到任何问题。

这是我在 HttpModule 事件处理程序中创建 cookie 的代码:

static void PreRequestHandlerExecute(Object sender, EventArgs e)
{
    HttpContext ctx = System.Web.HttpContext.Current;
        string authToken = ctx.Request.Params["wctoken"];
        if (!String.IsNullOrEmpty(authToken))
        {
            personInfo = WebApplicationUtilities.GetPersonInfo(authToken);
            WebApplicationUtilities.SavePersonInfoToCookie(ctx, personInfo);

            NameValueCollection query = HttpUtility.ParseQueryString(ctx.Request.Url.Query);
            query.Remove("wctoken");
            query.Remove("suggestedtokenttl");

            UriBuilder newUrl = new UriBuilder(ctx.Request.Url);
            newUrl.Query = query.ToString();
            //app.Response.Redirect(newUrl.Uri.OriginalString);
        }
}

请注意,重定向已被注释。在第一个请求(经过身份验证后)创建 cookie,然后我的默认操作能够使用 LoadPersonInfoFromCookie() 读取它。我发现做重定向导致cookie没有被发送到客户端。

我还注意到,在后续请求中,cookie 不存在于 Request.Cookies 集合中,因此当 LoadPersonInfoFromCookie() 运行时,我最终得到一个空值。奇怪的是在Response对象中可以看到cookie,但是内容是空的。

这里是动作代码,只是因为...

public HttpContext Context
{
    get { return System.Web.HttpContext.Current; }
}

public ActionResult Dashboard()
    {
        try
        {
            HealthVaultAccountModel model = new HealthVaultAccountModel();
            PersonInfo personInfo = WebApplicationUtilities.LoadPersonInfoFromCookie(Context);
            if (personInfo != null)
                model.PersonName = personInfo.Name;
            return View(model);
        }
        catch (Exception ex)
        {
            return RedirectToAction("Index", "Error");
        }
    }

更新

这是来自即时窗口的 cookie。我什至将过期时间延长了 30 天。

在创建后的默认操作中

Context.Request.Cookies["_wcpage"]
{System.Web.HttpCookie}
    Domain: null
    Expires: {8/13/2012 5:24:02 PM}
    HasKeys: true
    HttpOnly: true
    Name: "_wcpage"
    Path: "/"
    Secure: true
    Shareable: false
    Value: "p=1:1234-pVTbctowEP0V..."
    Values: {p=1%3a1234-pVTbctowEP0V...}

在下一个请求的操作中

Context.Request.Cookies["_wcpage"]
null

有趣的是,cookie 是在响应对象中定义的,但值已经消失,并且过期时间被重置。

Context.Response.Cookies["_wcpage"]
{System.Web.HttpCookie}
    Domain: null
    Expires: {1/1/0001 12:00:00 AM}
    HasKeys: false
    HttpOnly: false
    Name: "_wcpage"
    Path: "/"
    Secure: false
    Shareable: false
    Value: ""
    Values: {}

【问题讨论】:

    标签: asp.net-mvc cookies persistence httpmodule healthvault


    【解决方案1】:

    您是如何创建/获取 cookie 的? WebApplicationUtilities 类上的 SavePersonInfoToCookieLoadPersonInfoFromCookie 方法将为您完成。

    开始请求:

    // given an authToken from the querystring/post values
    var personInfo = WebApplicationUtilities.GetPersonInfo(authToken);
    WebApplicationUtilities.SavePersonInfoToCookie(application.Context, personInfo);
    

    控制器:

    var personInfo = WebApplicationUtilities.LoadPersonInfoFromCookie(HttpContext);
    

    【讨论】:

    • 我很好奇你是否真的让它在 MVC 应用程序中工作。
    • 我猜你的测试应用没有使用https。 cookie 的Secure 属性意味着它只能在https 连接上发送/访问。您可以通过将<add key="WCPage_SSLForSecure" value="false" /> 添加到web.config<appSettingsUser> 部分来禁用它。此外,为了将来参考,如果还没有找到一个空 cookie,则执行 Context.Response.Cookies["foo"] 实际上会创建一个空 cookie。在Response 对象中测试cookie 的唯一方法是遍历它们。为了回答您的问题,是的,我在 MVC 应用程序中完成了此操作。
    • 就是这样。我今天下午想通了。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2013-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-31
    • 2012-12-17
    相关资源
    最近更新 更多