C# Windows Phone 7 Mango保存CookieContainer的状态

C# Windows Phone 7 Mango保存CookieContainer的状态,c#,windows-phone-7,cookiecontainer,C#,Windows Phone 7,Cookiecontainer,更新1:经过更多的研究,我不确定这是否可行 我正试图在应用程序退出时或墓碑出现时保存CookieContainer,但我遇到了一些问题 在做了更多的研究之后,我们的工作似乎是从容器中取出饼干,然后用另一种方式保存它们。在我遇到另一个障碍之前,这一切都很顺利。我无法获取Uri为.mydomain.com的Cookie。我相信这是因为。我可以在域名表中看到cookie、.mydomain.com,但GetCookies在特定的cookie上不起作用 从容器中取出饼干也有问题 当域以a开头时: 我

更新1:经过更多的研究,我不确定这是否可行

我正试图在应用程序退出时或墓碑出现时保存CookieContainer,但我遇到了一些问题

在做了更多的研究之后,我们的工作似乎是从容器中取出饼干,然后用另一种方式保存它们。在我遇到另一个障碍之前,这一切都很顺利。我无法获取Uri为.mydomain.com的Cookie。我相信这是因为。我可以在域名表中看到cookie、.mydomain.com,但GetCookies在特定的cookie上不起作用

从容器中取出饼干也有问题 当域以a开头时:

我找到了一个解决方法,使用反射来迭代域表并删除“.”前缀

private void BugFix_CookieDomain(CookieContainer cookieContainer)
{
    System.Type _ContainerType = typeof(CookieContainer);
    var = _ContainerType.InvokeMember("m_domainTable",
                               System.Reflection.BindingFlags.NonPublic |
                               System.Reflection.BindingFlags.GetField |
                               System.Reflection.BindingFlags.Instance,
                               null,
                               cookieContainer,
                               new object[] { });
    ArrayList keys = new ArrayList(table.Keys);
    foreach (string keyObj in keys)
    {
        string key = (keyObj as string);
        if (key[0] == '.')
        {
            string newKey = key.Remove(0, 1);
            table[newKey] = table[keyObj];
        }
    }
}
只有调用InvokeMember时,才会在SL中抛出MethodAccessException。这并不能真正解决我的问题,因为我需要保留的cookie之一是HttpOnly,这也是CookieContainer的原因之一

如果服务器发送HTTPOnly cookies,您应该创建一个 System.Net.CookieContainer在请求保存cookie时, 尽管您将无法看到或访问以下cookie: 储存在容器中


有什么想法吗?我错过了一些简单的东西吗?是否有其他方法可以保存CookieContainer的状态,或者我是否需要保存用户信息(包括密码),并在每次应用程序启动时以及从墓碑记录中返回时重新验证用户信息?

在WP7中,您无法访问程序集之外的私有成员,即使使用反射。这是一种安全措施,用于确保您不能调用内部系统API


看起来你可能运气不好。

我写了一个CookieSerializer,专门解决这个问题。序列化程序粘贴在下面。对于工作项目和场景,请访问项目的


是的,你会认为这是一件很简单的事情。这对wp7有用吗?我不认为wp7支持的HTTPOnly cookies.HTTPOnly cookies将出现,但它将被隐藏,即使您无法读取代码。您可以做的是:您可以在接下来的所有后续请求中一次又一次地重新分配相同的CookieContainer。
CookieContainer container = new CookieContainer();
container.Add(new Cookie("x", "1", "/", ".blah.com"));
CookieCollection cv = container.GetCookies(new Uri("http://blah.com"));
cv = container.GetCookies(new Uri("http://w.blah.com"));
private void BugFix_CookieDomain(CookieContainer cookieContainer)
{
    System.Type _ContainerType = typeof(CookieContainer);
    var = _ContainerType.InvokeMember("m_domainTable",
                               System.Reflection.BindingFlags.NonPublic |
                               System.Reflection.BindingFlags.GetField |
                               System.Reflection.BindingFlags.Instance,
                               null,
                               cookieContainer,
                               new object[] { });
    ArrayList keys = new ArrayList(table.Keys);
    foreach (string keyObj in keys)
    {
        string key = (keyObj as string);
        if (key[0] == '.')
        {
            string newKey = key.Remove(0, 1);
            table[newKey] = table[keyObj];
        }
    }
}
public static class CookieSerializer
{
    /// <summary>
    /// Serializes the cookie collection to the stream.
    /// </summary>
    /// <param name="cookies">You can obtain the collection through your <see cref="CookieAwareWebClient">WebClient</see>'s <code>CookieContainer.GetCookies(Uri)</code>-method.</param>
    /// <param name="address">The <see cref="Uri">Uri</see> that produced the cookies</param>
    /// <param name="stream">The stream to which to serialize</param>
    public static void Serialize(CookieCollection cookies, Uri address, Stream stream)
    {
        using (var writer = new StreamWriter(stream))
        {
            for (var enumerator = cookies.GetEnumerator(); enumerator.MoveNext();)
            {
                var cookie = enumerator.Current as Cookie;
                if (cookie == null) continue;
                writer.WriteLine(address.AbsoluteUri);
                writer.WriteLine(cookie.Comment);
                writer.WriteLine(cookie.CommentUri == null ? null : cookie.CommentUri.AbsoluteUri);
                writer.WriteLine(cookie.Discard);
                writer.WriteLine(cookie.Domain);
                writer.WriteLine(cookie.Expired);
                writer.WriteLine(cookie.Expires);
                writer.WriteLine(cookie.HttpOnly);
                writer.WriteLine(cookie.Name);
                writer.WriteLine(cookie.Path);
                writer.WriteLine(cookie.Port);
                writer.WriteLine(cookie.Secure);
                writer.WriteLine(cookie.Value);
                writer.WriteLine(cookie.Version);
            }
        }
    }

    /// <summary>
    /// Deserializes <see cref="Cookie">Cookie</see>s from the <see cref="Stream">Stream</see>, 
    /// filling the <see cref="CookieContainer">CookieContainer</see>.
    /// </summary>
    /// <param name="stream">Stream to read</param>
    /// <param name="container">Container to fill</param>
    public static void Deserialize(Stream stream, CookieContainer container)
    {
        using (var reader = new StreamReader(stream))
        {
            while (!reader.EndOfStream)
            {
                var uri = Read(reader, absoluteUri => new Uri(absoluteUri, UriKind.Absolute));
                var cookie = new Cookie();
                cookie.Comment = Read(reader, comment => comment);
                cookie.CommentUri = Read(reader, absoluteUri => new Uri(absoluteUri, UriKind.Absolute));
                cookie.Discard = Read(reader, bool.Parse);
                cookie.Domain = Read(reader, domain => domain);
                cookie.Expired = Read(reader, bool.Parse);
                cookie.Expires = Read(reader, DateTime.Parse);
                cookie.HttpOnly = Read(reader, bool.Parse);
                cookie.Name = Read(reader, name => name);
                cookie.Path = Read(reader, path => path);
                cookie.Port = Read(reader, port => port);
                cookie.Secure = Read(reader, bool.Parse);
                cookie.Value = Read(reader, value => value);
                cookie.Version = Read(reader, int.Parse);
                container.Add(uri, cookie);
            }
        }
    }

    /// <summary>
    /// Reads a value (line) from the serialized file, translating the string value into a specific type
    /// </summary>
    /// <typeparam name="T">Target type</typeparam>
    /// <param name="reader">Input stream</param>
    /// <param name="translator">Translation function - translate the read value into 
    /// <typeparamref name="T"/> if the read value is not <code>null</code>.
    /// <remarks>If the target type is <see cref="Uri">Uri</see> , the value is considered <code>null</code> if it's an empty string.</remarks> </param>
    /// <param name="defaultValue">The default value to return if the read value is <code>null</code>.
    /// <remarks>The translation function will not be called for null values.</remarks></param>
    /// <returns></returns>
    private static T Read<T>(TextReader reader, Func<string, T> translator, T defaultValue = default(T))
    {
        var value = reader.ReadLine();
        if (value == null)
            return defaultValue;
        if (typeof(T) == typeof(Uri) && String.IsNullOrEmpty(value))
            return defaultValue;
        return translator(value);
    }
}