如何在ASP.NET Core中处理多值Cookie?

11
在完整的 .NET 框架中,我们支持多值 Cookie。例如,一个 Cookie 可以有多个值:
HttpCookie aCookie = new HttpCookie("userInfo");
aCookie.Values["userName"] = "patrick";
aCookie.Values["lastVisit"] = DateTime.Now.ToString();

请参阅MSDN上关于HttpCookie.Values的文档以及MSDN上ASP.NET Cookies概述

在ASP.NET Core中,似乎没有多值cookie。没有HttpCookie.ValuesHttpRequest.Cookies返回一个类似于从stringstringdictionaryIRequestCookieCollection

我应该如何在ASP.NET Core中创建和读取多值cookie?我该如何读取在Full ASP.NET中创建的多值cookie并在ASP.NET Core中读取它们?


1
你尝试过读取“遗留”的cookie吗?这可能会提供一些见解。遗留的NameValueCollection可以相当直接地序列化为/从字符串。找出为什么核心不支持遗留的多值cookie是很有趣的。 - Mark Larter
2个回答

35

我认为ASP.NET Core移除对旧版多值Cookie的支持是因为该功能从未被标准化。

RFC定义Cookies明确指出,使用Set-Cookie头,您可以分配一个单独的名称/值对,并且可以关联元数据。

.NET HttpCookie的官方实现非常脆弱,只是将键值对序列化/反序列化为字符串,并使用&作为对键值对之间的分隔符,=作为对键和值之间的分隔符。

在ASP.NET Core中模拟这种行为应该相当容易,您可以使用扩展方法来处理那些旧版格式的cookie:

public static class LegacyCookieExtensions
{
    public static IDictionary<string, string> FromLegacyCookieString(this string legacyCookie)
    {
        return legacyCookie.Split('&').Select(s => s.Split('=')).ToDictionary(kvp => kvp[0], kvp => kvp[1]);
    }

    public static string ToLegacyCookieString(this IDictionary<string, string> dict)
    {
        return string.Join("&", dict.Select(kvp => string.Join("=", kvp.Key, kvp.Value)));
    }
}

像这样使用它们:

// read the cookie
var legacyCookie = Request.Cookies["userInfo"].FromLegacyCookieString();
var username = legacyCookie["userName"];

// write the cookie
var kvpCookie = new Dictionary<string, string>()
{
    { "userName", "patrick" },
    { "lastVisit", DateTime.Now.ToString() }
};
Response.Cookies.Append("userInfo", kvpCookie.ToLegacyCookieString());

演示: https://dotnetfiddle.net/7KrJ5S

如果您需要更复杂的序列化/反序列化逻辑(处理cookie值中的格式错误和转义字符),您应该查看并从Mono HttpCookie实现中获取一些代码,我相信它更加健壮。


你如何将Mono HttpCookie实现集成到正在运行的ASP.NET Core系统中? - Necroqubus
请注意,ASP.NET Core将对cookie值中的特殊字符(例如=)进行编码。因此,如果您需要与旧应用程序进行互操作性,则需要在此处寻找解决方案:https://dev59.com/Nqjja4cB1Zd3GeqP9FMz#48324815 - mbp

4
CookieManager包装器允许您操作对象。在asp.net core中,您可以轻松地读取/写入对象。它为您提供加密cookie值以保护数据的选项。
请查看:https://github.com/nemi-chand/CookieManager 创建您想要存储在cookie中的poco/object。
public class MyCookie
{
  public string Id { get; set; }

  public DateTime Date { get; set; }

  public string Indentifier { get; set; }
}

填充对象值

MyCookie cooObj= new MyCookie()
{
  Id = Guid.NewGuid().ToString(),
  Indentifier = "valueasgrsdgdf66514sdfgsd51d65s31g5dsg1rs5dg",
  Date = DateTime.Now
};

设置myCookie对象。
_cookieManager.Set("Key", cooObj, 60);

获取 myCookie 对象

MyCookie objFromCookie = _cookieManager.Get<MyCookie>("Key");

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